如何使用ggplot2制作这样的条形图

时间:2016-04-29 02:14:03

标签: r ggplot2

如何制作如下图所示的条形图?

Fig.1

我已经尝试了,但只能得到这个:

Fig.2

这是我的代码:

ggplot(N.Balance, aes(x = factor(Period), y = value)) + 
geom_bar(stat = "identity", aes( group = Type, fill = variable), osition = "stack", width = 0.6) +
facet_wrap(~ Type,ncol = 1) +
coord_flip() +
scale_fill_grey() + 
theme_bw(base_size = 30, base_family = "serif") + 
labs(y = expression(paste("kg", " ", "N", " ", ha^{-1}))) + 
theme(legend.key.height = unit(0.5, "in"))

数据显示如下:

structure(list(Period = c("2007R", "2007/2008W", "2008R", "2008/2009W", 
"2009R", "2009/2010W", "2007R", "2007/2008W", "2008R", "2008/2009W", 
"2009R", "2009/2010W", "2007R", "2007/2008W", "2008R", "2008/2009W", 
"2009R", "2009/2010W", "2007R", "2007/2008W", "2008R", "2008/2009W", 
"2009R", "2009/2010W", "2007R", "2007/2008W", "2008R", "2008/2009W", 
"2009R", "2009/2010W", "2007R", "2007/2008W", "2008R", "2008/2009W", 
"2009R", "2009/2010W", "2007R", "2007/2008W", "2008R", "2008/2009W", 
"2009R", "2009/2010W", "2007R", "2007/2008W", "2008R", "2008/2009W", 
"2009R", "2009/2010W", "2007R", "2007/2008W", "2008R", "2008/2009W", 
"2009R", "2009/2010W", "2007R", "2007/2008W", "2008R", "2008/2009W", 
"2009R", "2009/2010W"), 
variable = c("Denitrification", "Denitrification", "Denitrification", "Denitrification",
"Denitrification", "Denitrification", "Runoff", "Runoff", "Runoff", "Runoff", "Runoff", 
"Runoff", "Leaching", "Leaching", "Leaching", "Leaching", "Leaching", "Leaching", "NH3Vol", 
"NH3Vol", "NH3Vol", "NH3Vol", "NH3Vol", "NH3Vol", "Harvest", 
"Harvest", "Harvest", "Harvest", "Harvest", "Harvest", "Fertilizer", 
"Fertilizer", "Fertilizer", "Fertilizer", "Fertilizer", "Fertilizer", 
"Fix", "Fix", "Fix", "Fix", "Fix", "Fix", "Irrigation", "Irrigation", 
"Irrigation", "Irrigation", "Irrigation", "Irrigation", "Seeds", 
"Seeds", "Seeds", "Seeds", "Seeds", "Seeds", "Deposition", "Deposition", 
"Deposition", "Deposition", "Deposition", "Deposition"), 
value = c(-89.4, -34.4, -61.5, -82.5, -87.2, -34.7, -21.8, -33.4, -2.65, -42.8, 
-19.2, -58.7, -8.22, -1.44, -9.76, -4.76, -4.97, -19, -71.6, 
-50.8, -97.1, -10.9, -60.6, -19.6, -187, -116, -167, -96, -177, 
-127, 300, 200, 300, 200, 300, 200, 45, 15, 45, 15, 45, 15, 12.5, 
0, 11.6, 0, 11.3, 0, 0.9, 3, 0.9, 3, 0.9, 3, 8.41, 13.74, 4.01, 
13.34, 16.31, 9.81), Type = c("O", "O", "O", "O", "O", "O", "O", 
"O", "O", "O", "O", "O", "O", "O", "O", "O", "O", "O", "O", "O", 
"O", "O", "O", "O", "O", "O", "O", "O", "O", "O", "I", "I", "I", 
"I", "I", "I", "I", "I", "I", "I", "I", "I", "I", "I", "I", "I", 
"I", "I", "I", "I", "I", "I", "I", "I", "I", "I", "I", "I", "I", "I")), 
.Names = c("Period", "variable", "value", "Type"), class = "data.frame", 
row.names = c(NA,  -60L))

请注意类型" O"意味着"输出"和"我"意味着"输入"

1 个答案:

答案 0 :(得分:3)

在评论中执行我要求的dput()会更有帮助,但我将print()输出替换为可能想要贡献的其他人。

至少有两种方式(比下面的方式)接近该图表。这个依赖于一个新兴的geom_,它允许你有coord_flip()的水平条 - 这意味着你可以玩小平面尺度:

library(ggplot2)
library(ggstance) # devtools::install_github("lionel-/ggstance")
library(dplyr)

N.Balance <- read.csv("~/Data/so.csv", stringsAsFactors=FALSE)
N.Balance$Period_f <- factor(N.Balance$Period)
N.Balance$Type_f <- factor(N.Balance$Type, 
                         levels=c("O", "I"),
                         labels=c("Output", "Input"))

gg <- ggplot(N.Balance, aes(x=value, y=Period_f))
gg <- gg + geom_barh(stat = "identity", 
                    aes(group = Type, fill = variable), 
                    position = "stack", width = 0.6)
gg <- gg + geom_text(data=data.frame(Period=unique(N.Balance$Period)),
                     aes(x=5, y=Period, label=Period),
                     color="white", hjust=0, size=3)
gg <- gg + scale_x_continuous(expand=c(0,-0.001))
gg <- gg + scale_fill_grey(name="")
gg <- gg + facet_wrap(~ Type_f, ncol=2, scales="free_x")
gg <- gg + guides(fill=guide_legend(keywidth = 2, keyheight = 1))
gg <- gg + labs(y=NULL, x = expression(paste("kg", " ", "N", " ", ha^{-1})))
gg <- gg + theme_bw()
gg <- gg + theme(legend.key.height = unit(0.5, "in"))
gg <- gg + theme(panel.background=element_blank())
gg <- gg + theme(panel.border=element_blank())
gg <- gg + theme(panel.margin=margin(l=0, r=0))
gg <- gg + theme(legend.position="top")
gg <- gg + theme(panel.grid=element_blank())
gg <- gg + theme(strip.background=element_blank())
gg <- gg + theme(axis.text.y=element_blank())
gg <- gg + theme(axis.ticks.y=element_blank())
gg <- gg + theme(legend.key=element_blank())
gg <- gg + theme(legend.text=element_text(size=8))
gg <- gg + theme()
gg

enter image description here

这个新的geom_barh()位于一个不在CRAN上的软件包中,所以如果这是一个问题,就像我说的那样 - 至少还有其他两种方式。

另一种方式为你提供了完全冲洗的条形图,并且只需geom_bar()就可以做到这一点,但需要进行一些数据争论和轴文本标签争论。你必须手工制作哪个facet标签可以免费获得(如果你需要输入/输出标签)。

如果你需要将图例分开(并进行一些额外的调整以使条纹齐平),那么最直接的方法是制作两个单独的图,编辑grob边距和&amp;使用grid.arrange()。如果在绘图标题中执行此操作,此方法还可以为您提供对齐的输入/输出标签。

这两个都是“工作”。

如果您需要图案填充,其他人将不得不帮助您。这是可行的,但很乏味。