如何在R中绘制两个正镜条形图?

时间:2020-08-07 11:52:22

标签: r ggplot2 bar-chart

我想在此处绘制类似于图像的图形:

enter image description here

我试图在Google上找到类似的镜像条形图,但找不到与上图类似的图。

图的棘手部分是1)y轴和+ ve都具有正值,以及2)y轴和ve都具有不同的y轴标记。

预先感谢您的帮助。

3 个答案:

答案 0 :(得分:1)

也许是这样?

library(ggplot2)

df <- data.frame(x = rep(letters[1:3], each = 4),
                 y = c(2, -2, 3, -3, 4, -4, 5, -5, 2, -2, 3, -3),
                 dodgegroup = factor(rep(rep(1:2, each = 2), 3)))

ggplot(df, aes(x, y, fill = dodgegroup))  +
  geom_col(position = position_dodge(width = 0.75), 
           colour = "black", width = 0.5) +
  geom_hline(aes(yintercept = 0)) +
  scale_fill_manual(values = c("white", "gray75")) +
  scale_y_continuous(breaks = 0:10 - 5,
                     labels = c(5:0, 5 * 1:5)) +
  theme_classic()

reprex package(v0.3.0)于2020-08-07创建

答案 1 :(得分:1)

这与我到该图为止的距离最近。

这真的很棘手。

  • Y轴的负极必须为正
  • 在负数侧,数字必须小5倍,因为Y轴上的数字小5倍[从1到5,而不是1到25]
  • 不确定性栏需要绘制
  • X标签加倍

我不能做的事情:

  • 以适当的方式设置Y轴名称,[如果有人知道并且可以提供帮助..!]
  • 了解a和b是什么以及用什么逻辑放置它们[您需要更好地解释这一点]

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"))
                    

enter image description here

答案 2 :(得分:0)

尝试一下。尽管Edo的答案最符合您的要求,但此方法不需要您转换数据。但是,轴两侧的比例相同。

两次调用%macro my_stp; proc http url='https://mysashost.com/SASStoredProcess/do_program=/MySTPDir/MyRsubmitProgram&_action=background'; run; <other code>; %mend; ,但在geom_col的值之前输入-,然后使用Root来使y轴的正数都为正: >

编辑-固定了y轴

labels=abs

enter image description here