使用diamonds
,我希望将carat
与price
联系为4个级别Fair
,Good
,Very Good
和{{1} } {}} {}
我没有让Premimum
控制轴上的断点,而是制作了四个图来控制轴的断点。
cut
RESULT
每个图都有一系列不同的y值
问题
在所有方面,x和y轴是相同的。唯一的区别是最小值,最大值和休息时间。我想在此图中添加x和y标签。我可以在任何word文档或图像编辑器中手动执行此操作。反正在R中直接做到了吗?
答案 0 :(得分:4)
除了使用gridExtra
包中的函数(由@ user20650建议)之外,您还可以通过将diamonds
数据框按{{1}级别分割来创建包含较少代码的图表并使用cut
。
以下答案还包括评论中后续问题的解决方案。我们展示了如何布置四个图,添加适用于所有图的单个x和y标签(包括使它们加粗并控制它们的颜色和大小),并获得单个图例而不是每个图的单独图例。 / p>
mapply
删除library(ggplot2)
library(gridExtra)
library(grid)
library(scales)
为cut
的行:
"Ideal"
创建四个图,每个剩余的dat = diamonds[diamonds$cut != "Ideal",]
dat$cut = droplevels(dat$cut)
级别一个并存储在列表中。我们使用cut
(而非mapply
),以便我们可以为lapply
的每个级别提供单独的数据框,并为自定义cut
值提供矢量以设置最高值在每个图上分别在y轴上。我们还添加ymax
以创建颜色图例:
color=clarity
好的,我们有四个地块,但每个都有自己的传说。所以现在我们要安排只有一个整体传奇。我们通过将一个图例作为单独的grob( gr aphical ob ject)提取,然后从四个图中删除图例来实现此目的。
使用小辅助函数将图例解压缩为单独的grob:
pl = mapply(FUN = function(df, ymax) {
ggplot(df, aes(carat, price, color=clarity))+
geom_point()+
facet_wrap(~cut, ncol=2)+
scale_x_continuous(limits = c(0,4), breaks=0:4)+
scale_y_continuous(limits = c(0, ymax), labels=dollar_format()) +
labs(x=expression(" "),
y=expression(" "))
}, df=split(dat, dat$cut), ymax=c(1e4,5e3,1e3,3e3), SIMPLIFY=FALSE)
现在我们需要在2x2网格中排列四个图,然后将图例放在此网格的右侧。我们使用# Function to extract legend
# https://github.com/hadley/ggplot2/wiki/Share-a-legend-between-two-ggplot2-graphs
g_legend<-function(a.gplot){
tmp <- ggplot_gtable(ggplot_build(a.gplot))
leg <- which(sapply(tmp$grobs, function(x) x$name) == "guide-box")
legend <- tmp$grobs[[leg]]
return(legend) }
# Extract legend as a grob
leg = g_legend(pl[[1]])
来绘制图表(并注意我们如何使用arrangeGrob
在渲染之前从每个图中删除图例)。这与我们在此答案的早期版本中对lapply
所做的基本相同,只是grid.arrange
创建2x2绘图网格对象而不绘制它。然后我们将整个事物包裹在arrangeGrob
内,在2x2绘图网格旁边布置图例。 grid.arrange
将水平空间的90%分配给2x2图形网格,将10%分配给图例。呼!
widths=c(9,1)