Как нарисовать положительную зеркальную гистограмму в r? - PullRequest
0 голосов
/ 07 августа 2020

Я хотел бы нарисовать график, подобный изображенному здесь:

введите описание изображения здесь

Я пытался найти похожие зеркальные гистограммы в Google, но не смог найти график, похожий на изображение выше.

Сложные части графика заключаются в том, что 1) оба + ve и -ve оси y имеют положительные значения, и 2) оси y + ve и -ve имеют разные обозначения оси y.

Заранее благодарим вас за вашу помощь.

Ответы [ 3 ]

1 голос
/ 07 августа 2020

Это максимально близко к тому графику.

Это действительно сложно.

  • Ось Y должна быть положительной на отрицательной стороне
  • На отрицательной стороне числа должны выглядеть в 5 раз меньше, поскольку число на оси Y в 5 раз меньше [от 1 до 5 вместо 1 до 25]
  • необходимо нарисовать столбцы неопределенности
  • Метки X удваиваются

Чего я не мог сделать:

  • правильно настроить имена оси Y, [если кто знает и может помогите ..!]
  • понять, что такое a и b и с какими логами c их разместить [вам нужно объяснить это лучше]

library(dplyr)
library(ggplot2)


# your data

n <- 100
set.seed(42)

df <- tibble(var1 = factor(rep(c("Mamou", "Crowley"), each = 8 * n), levels = c("Mamou", "Crowley"), ordered = TRUE),
                         var2 = factor(rep(c("RWW-M1", "RWW-M2", "RWW-C1", "RWW-C2"), each = 4* n), levels = c("RWW-M1", "RWW-M2", "RWW-C1", "RWW-C2"), ordered = TRUE),
                         var3 = factor(rep(rep(c("Shoot dry weight (g)", "Root dry weight (g)"), each = 2*n), 4), levels = c("Shoot dry weight (g)", "Root dry weight (g)"), ordered = TRUE),
                         varc = rep(rep(c("white", "black"), each = n), 8),
                         value = abs(c(
                            rnorm(2*n, mean = 5  , sd = 0.2),
                            rnorm(2*n, mean = 3  , sd = 0.04),
                            rnorm(2*n, mean = 15 , sd = 0.2), 
                            rnorm(2*n, mean = 4  , sd = 0.04), 
                            rnorm(2*n, mean = 5  , sd = 0.2), 
                            rnorm(2*n, mean = 2.5, sd = 0.04), 
                            rnorm(2*n, mean = 5  , sd = 0.2),
                            rnorm(2*n, mean = 2.5, sd = 0.04))))


# edit your data this way [a little trick to set bars up and down the line and make them look like 5 times bigger]
df <- df %>% mutate(value = if_else(var3 == "Root dry weight (g)", -value*5, value))


# calculate statistics you want to plot
df <- df %>%
    group_by(var1, var2, var3, varc) %>% 
    summarise(mean = mean(value), min = min(value), max = max(value)) %>% 
    ungroup()


df %>%
    ggplot(aes(x = var2)) +
    
    # plot dodged bars
    geom_col(aes(y = mean, fill = varc),
                     position = position_dodge(width = 0.75), 
                     colour = "black", width = 0.5) +
    
    
    # plot dodged errorbars
    geom_errorbar(aes(ymin = min, ymax = max, group = varc),
                                position = position_dodge(width = 0.75), width = 0.2, size = 1) + 
    
    # make line on zero more visible
    geom_hline(aes(yintercept = 0)) +

    # set up colour of the bars, don't show legend
    scale_fill_manual(values = c("white", "gray75"), guide = FALSE) +
    
    # set up labels of y axis
    # dont change positive, make negative look positive and 5 times smaller
    # set up breaks every 5 [ggplot will calc labels after breaks]
    scale_y_continuous(labels = function(x) if_else(x<0, -x/5, x), 
                                         breaks = function(x) as.integer(seq(x[1]-x[1]%%5, x[2]-x[2]%%5, 5))) +  
    
    # put labels and x axis on top
    scale_x_discrete(position = "top") +
    
    # set up var1 labels on top
    facet_grid( ~ var1, space = 'free', scales = 'free') +
    
    
    # show proper axis names
    labs(x = "", y = "Root dry weight (g)                       Shoot dry weight (g)") +
    
    # set up theme
    theme_classic() +
    theme(axis.line.x = element_blank(), 
                axis.ticks.x = element_blank(), 
                panel.grid = element_blank(),  
                
                # this is to put names of facet grid on top
                strip.placement = 'outside',
                
                # this is to remove background from labels on facet grid
                strip.background = element_blank(),
                
                # this is to make facets close to each other
                panel.spacing.x = unit(0,"line"))
                    

введите описание изображения здесь

1 голос
/ 07 августа 2020

Что-то вроде этого, возможно?

0 голосов
/ 07 августа 2020

Попробуйте это. Хотя ответ Эдо больше всего похож на то, что вы просили, этот метод не требует от вас преобразования ваших данных. Однако масштаб по обе стороны от оси одинаков.

Вызов geom_col дважды, но с - перед значениями Root, затем мы используем labels=abs, чтобы сделать обе стороны Положительные числа по оси Y:

Edit - исправлена ​​ось Y

library(ggplot2)

df <- data.frame(x = rep(c("RWW-M1", "RWW-M2", "RWW-C1", "RWW-C2"), each = 2),
                 Shoot = c(5, 6, 7, 8, 4, 5, 5, 7),
                 Root = c(1, 2, 3, 4, 2, 3, 1, 2),
                 Condition = rep(c("control", "test"), each = 1))

p <- ggplot(df, aes(x=x, fill=Condition)) + 
  geom_col(aes(y=Shoot), position = position_dodge(width = 0.75), width = 0.5, colour = "black")+ 
  geom_col(aes(y=-Root), position = position_dodge(width = 0.75), width = 0.5, colour = "black")+
  geom_hline(aes(yintercept = 0)) +
  scale_fill_manual(values = c("white", "gray75")) +
  ylab("Root weight (g)   /   Shoot weight (g)")+
  xlab("")+
  scale_y_continuous(breaks = 0:15 - 5, labels=abs) +
  theme_bw()
p

введите описание изображения здесь

...