条形图的误差条仅在一个方向上

时间:2014-12-20 22:46:26

标签: r plot ggplot2 bar-chart data-visualization

是否可以调整ggplot2中的错误栏,以便它们仅在一个方向上绘制(例如,仅向上但不向下)?

df <- data.frame(trt = factor(c(1, 1, 2, 2)), resp = c(1, 5, 3, 4),
                 group = factor(c(1, 2, 1, 2)), se = c(0.1, 0.3, 0.3, 0.2))
df2 <- df[c(1,3), ]

limits <- aes(ymax = resp + se, ymin = resp - se)
dodge <- position_dodge(width = 0.9)

p <- ggplot(df, aes(fill = group, y = resp, x = trt))
p + geom_bar(position = dodge, stat = "identity") +
    geom_errorbar(limits, position = dodge, width = 0.25)

Rplot

4 个答案:

答案 0 :(得分:12)

一个简单的解决方法是首先绘制误差线:

p +
  geom_errorbar(limits, position = dodge, width=0.25) +
  geom_bar(position = dodge, stat = "identity")

enter image description here

答案 1 :(得分:5)

在这种情况下,亨里克的建议非常好,但我建议你看一下上限和下限的设定位置。

 limits <- aes(ymax = resp + se, ymin = resp - se)

在该行中,您明确告诉ggplot通过将ymin设置为resp - se来放置较低的扩展名;如果您只是将其设置为resp,那么您只有上限扩展名。

 limits <- aes(ymax = resp + se, ymin = resp)

...虽然你的栏顶部也有黑线。为了使其看起来更干净,您可以为整个条形添加黑色轮廓。

p <- ggplot(df, aes(fill = group, y = resp, x = trt))+
  geom_bar(position = dodge, stat = "identity") +
  geom_bar(position = dodge, stat = "identity", 
           color="black", show_guide=FALSE)+
  geom_errorbar(limits, position = dodge, width = 0.25)
p

bar plot

注意我是如何复制条形图图层的,但是使用了&#34;黑色&#34;颜色,增加了轮廓。图例在彩色图层中被关闭,因为我个人更喜欢避开图例中的对角线。

答案 2 :(得分:4)

实际上很容易实现这个用于一般情况(你不能隐藏另一个绘图元素下的下方错误条),因为他们已经很容易使用自定义{ggplot2进行扩展{1}}秒。

geom中的代码从geom_errorbar的github存储库复制到新的.R文件中。然后进行一些修改,如下:

ggplot2

上面所需的唯一两项更改是将geom_uperrorbar <- function(mapping = NULL, data = NULL, stat = "identity", position = "identity", ..., na.rm = FALSE, show.legend = NA, inherit.aes = TRUE) { layer( data = data, mapping = mapping, stat = stat, geom = GeomUperrorbar, position = position, show.legend = show.legend, inherit.aes = inherit.aes, params = list( na.rm = na.rm, ... ) ) } 更改为geom_errorbar,将geom_uperrorbar更改为geom = GeomErrorbar

geom = GeomUperrorbar

请注意,此注释在中途中断函数,该函数在下面的代码块中继续。上面我们刚刚将GeomUperrorbar <- ggproto("GeomUperrorbar", Geom, default_aes = aes(colour = "black", size = 0.5, linetype = 1, width = 0.5, alpha = NA), draw_key = draw_key_path, 更改为GeomErrorbar两次。

GeomUperrorbar

再次中断该功能。上面我们将所需的美学更改为 required_aes = c("x", "y", "ymax"), setup_data = function(data, params) { data$width <- data$width %||% params$width %||% (resolution(data$x, FALSE) * 0.9) transform(data, xmin = x - width / 2, xmax = x + width / 2, width = NULL ) }, xy,即将ymax替换为ymin。我们需要y在那里开始垂直线(而不是y),我们不再需要ymin,因为那里不会有水平线。

ymin

这里我们删除了传递给 draw_panel = function(data, panel_scales, coord, width = NULL) { GeomPath$draw_panel(data.frame( x = as.vector(rbind(data$xmin, data$xmax, NA, data$x, data$x)), y = as.vector(rbind(data$ymax, data$ymax, NA, data$ymax, data$y)), colour = rep(data$colour, each = 5), alpha = rep(data$alpha, each = 5), size = rep(data$size, each = 5), linetype = rep(data$linetype, each = 5), group = rep(1:(nrow(data)), each = 5), stringsAsFactors = FALSE, row.names = 1:(nrow(data) * 5) ), panel_scales, coord) } ) x的向量的最后三个元素,这些元素用于较低的错误栏。此外,我们将最后一个元素从y更改为ymin,因为我们希望该行从y开始,而不是y

ymin

最后一位只是需要定义的代码中使用的便捷函数。

如果您使用包含所有此类代码的文档来源,那么您可以使用"%||%" <- function(a, b) { if (!is.null(a)) a else b } ,就像geom_uperrorbar一样,或者甚至将geom_errorbar传递给geom = "uperrorbar",使用{{1而不是stat_summary

答案 3 :(得分:1)

如果所有条形都大于误差条,则Henriks应答有效。但是,如果您的误差线大于数据条,则“底部”的尾端会出现。将看到tail(正数据条的负误差条,反之亦然),因为它将穿过0 y轴。如果所有数据都在同一方向,则可以将限制ymin设置为0。

这种方法的问题在于,如果您有混合数据条(一些是正数而一些是负数),则无法将限制设置为0.例如,如果原始数据是:

df <- data.frame(trt = factor(c(1, 1, 2, 2)), resp = c(1, 5, -3, 4),
             group = factor(c(1, 2, 1, 2)), se = c(2, 0.3, 4, 0.2))
df2 <- df[c(1,3), ]

limits <- aes(ymax = resp + se, ymin = resp - se)
dodge <- position_dodge(width = 0.9)

p <- ggplot(df, aes(fill = group, y = resp, x = trt))
p + geom_errorbar(limits, position = dodge, width = 0.25) +
    geom_bar(position = dodge, stat = "identity") 

结果图的误差条将延伸到trt 1,group 1和trt 2,group1之下。

这可以通过使用ifelse()子句调整限制语句来修复:

limits <- aes(ymax = ifelse(resp>0,resp + se,resp/2),
              ymin = ifelse(resp<0,resp - se,resp/2))

p + geom_errorbar(limits, position = dodge, width = 0.25) +
    geom_bar(position = dodge, stat = "identity") 

在这种情况下,如果数据为正,则误差条max保持正常,但误差条min被调整为数据条高度的一半,因此它仍然隐藏在数据条的后面。