ggplot:如何使用箭头

时间:2018-01-08 07:32:41

标签: r ggplot2 bar-chart

目前我正在为海报展示复制/更新某些图形。我设法复制了图形的颜色,值,条形和背景。但是缺少箭头标签,突出了价值差异。我想知道是否有一个有用的选项通过ggplot(线或箭头),值得努力 - 或者我必须用另一个图形软件绘制一些箭头......

这是我尝试做的事情:

enter image description here

这是我已经拥有的东西:

enter image description here

数据和代码:

weight <- c(113.2158, 108.5404, 98.75564, 93.93759)
sex <- c("m","m", "f","f")
time <- c("t0", "t1", "t0", "t1")
data <- data.frame(weight, sex, time)
library(ggplot2)

ggplot(data, aes(x = factor(sex), y = weight, group=time, fill=factor(time))) + 
  geom_bar(position="dodge", stat = "identity") +
  theme(legend.position = c(0.8, 0.9),                                
        axis.ticks = element_blank(),                                 
        axis.title.x=element_blank(),                                 
        axis.title.y=element_blank(),                                 
        panel.background = element_blank(),                           
        panel.grid.major.x = element_blank() ,                        
        panel.grid.major.y = element_line( size=.1, color="grey" ),
        legend.key = element_rect(size = 2),
        legend.key.size = unit(1.5, 'lines')) +       
  guides(fill=guide_legend(title="time")) +                             
  scale_fill_manual(values=c("#b6181f", "#f6b8bb"), labels=c("t0", "t1")) +
  scale_x_discrete(labels = c("male, n = 57", "female, n = 133"))  +
  coord_cartesian(ylim = c(90,120)) +
  scale_y_continuous(breaks=c(90,95,100,105,110,115,120)) + 
  geom_text(aes(x=factor(sex), label=round(weight, digits=2)), position = position_dodge(width = 1), vjust = -0.25) +
  geom_line(aes(x=factor(sex), label=round(weight, digits=2)), position = position_dodge(width = 1), vjust = -0.25)

非常感谢你的想法。

1 个答案:

答案 0 :(得分:2)

这是一个可能的解决方案,试图复制原始情节的精神,除了用直箭头替换弯曲的箭头。 (如果你想要带有多个弯头的箭头,可能更容易在PowerPoint中实现效果......)

定义用于计算每组中条形高度差异的函数:

fun.data <- function(x){
  return(data.frame(y = max(x) + 1,
                    label = paste0(round(diff(x), 2), "cm")))
}

定义轴断点的功能(这比对轴标签进行硬编码更灵活,特别是如果您需要更改coord_cartesian的范围):

ab = 5 # let axis break labels be multiples of 5
fun.breaks <- function(limits){seq(ceiling(limits[1] / ab) * ab,
                                   floor(limits[2] / ab) * ab,
                                   by = ab)}

简介:

ggplot(data,
       aes(x = sex, y = weight, group = time, fill = time, label = round(weight, 2))) +

  # this segment creates the bar plot with labels just inside the top of each bar
  # note: geom_col() is equivalent to geom_bar(stat = "identity"), with less typing
  geom_col(position = "dodge") +
  geom_text(position = position_dodge(width = 0.9),
            vjust = 1.1) +

  # this segment creates the arrows & labels for the differences
  geom_line(aes(group = sex), position = position_nudge(0.1),
            arrow = arrow()) +
  stat_summary(aes(x = sex, y = weight), 
               geom = "label",
               fun.data = fun.data,
               fontface = "bold", fill = "lightgrey",
               inherit.aes = FALSE) +

  # set scales
  # note: use named vectors for fill & x to ensure that labels are mapped correctly
  scale_fill_manual(name = "time", 
                    values = c("t0" = "#b6181f", "t1" = "#f6b8bb"),
                    labels = c("beginning", "after 3 months")) +
  scale_x_discrete(name = "", 
                   labels = c("f" = "female, n = 133", "m" = "male, n = 57")) +
  scale_y_continuous(name = "",
                     breaks = fun.breaks,
                     minor_breaks = NULL) +

  # other cosmetic aspects
  coord_cartesian(ylim = c(90, 120)) +
  theme_classic() +
  theme(panel.grid.major.y = element_line(colour = "grey"))

plot