将多个ggplot图与有或没有图例对齐 [英] Align multiple ggplot graphs with and without legends

查看:409
本文介绍了将多个ggplot图与有或没有图例对齐的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图用ggplot绘制一张图来比较两个变量的绝对值,并且还显示它们之间的比率。由于比例是无单位的,而且值不是,所以我不能在同一个y轴上显示它们,所以我想垂直堆叠成两个带有对齐x轴的单独图形。



以下是我到目前为止所得到的结果:


  library(ggplot2)
library(dplyr)$ b $ pngalt =在这里输入图片说明>

b库(gridExtra)

#准备一些示例数据。
results< - data.frame(index =(1:20))
results $ control< - 50 * results $ index
results $ value< - results $ index * 50 + 2.5 * results $ index ^ 2 - results $ index ^ 3/8
results $ ratio< - results $ value / results $ control

#绘制绝对值
plot_values < - ggplot(aes(x = index))+
geom_point(aes(y = value,color =value))+
geom_point(aes(y = control,color =控制))


plot_ratios < - ggplot(结果,aes(x = index,y =比率))+
geom_point()

#将两个图重叠在一起
grid.arrange(plot_values,plot_ratios,ncol = 1,nrow = 2)

最大的问题在于第一个图的右侧的图例使其具有不同的大小。一个小问题是,我宁愿不在顶部图上显示X轴名称和刻度线,以避免混乱,并明确表示它们共享同一个轴。



我已经看过这个问题及其答案:



在ggplot中对齐绘图区域



不幸的是,这两个答案都不适合我。刻面看起来不太合适,因为我想为我的两个图形制作完全不同的y刻度。操纵ggplot_gtable返回的尺寸似乎更有希望,但我不知道如何解决这两个图具有不同数量的单元的事实。天真地复制该代码似乎没有改变我的情况下产生的图形尺寸。



这是另一个类似的问题:



在ggplot中对齐图的风险



这个问题本身似乎意味着一个很好的选择,但是rbind.gtable会抱怨如果表格有不同数量的列,这是由于图例造成的。也许有一种方法可以在第二个表中插入额外的空列?或者一种方法来抑制第一个图中的图例,然后将它重新添加到组合图中?

解决方案

这里有一个解决方案这并不需要明确使用网格图形。它使用构面,并隐藏比例的图例条目(使用 https://stackoverflow.com/a/21802022\"/a >。

  library(reshape2)

results_long< - melt(results,id.vars (result_long $变量==ratio,ratio,values)
results_long $ facet< - factor(results_long $ facet,=index)
results_long $ facet< - ifelse levels = c(values,ratio))

ggplot(results_long,aes(x = index,y = value,color = variable))+
geom_point()+
facet_grid(facet〜。,scales =free_y)+
scale_colour_manual(breaks = c(control,value),
values = c(#1B9E77, (color = guide_legend(title)),其中包含一个主题元素(例如D95F02,#7570B3))+
主题(legend.justification = c(0,1),legend.position = c(0,1))+
guides =


















$ b $


I'm trying to use ggplot to draw a graph comparing the absolute values of two variables, and also show the ratio between them. Since the ratio is unitless and the values are not, I can't show them on the same y-axis, so I'd like to stack vertically as two separate graphs with aligned x-axes.

Here's what I've got so far:

library(ggplot2)
library(dplyr)
library(gridExtra)

# Prepare some sample data.
results <- data.frame(index=(1:20))
results$control <- 50 * results$index
results$value <- results$index * 50 + 2.5*results$index^2 - results$index^3 / 8
results$ratio <- results$value / results$control

# Plot absolute values
plot_values <- ggplot(results, aes(x=index)) +
  geom_point(aes(y=value, color="value")) +
  geom_point(aes(y=control, color="control"))

# Plot ratios between values
plot_ratios <- ggplot(results, aes(x=index, y=ratio)) +
  geom_point()

# Arrange the two plots above each other
grid.arrange(plot_values, plot_ratios, ncol=1, nrow=2)

The big problem is that the legend on the right of the first plot makes it a different size. A minor problem is that I'd rather not show the x-axis name and tick marks on the top plot, to avoid clutter and make it clear that they share the same axis.

I've looked at this question and its answers:

Align plot areas in ggplot

Unfortunately, neither answer there works well for me. Faceting doesn't seem a good fit, since I want to have completely different y scales for my two graphs. Manipulating the dimensions returned by ggplot_gtable seems more promising, but I don't know how to get around the fact that the two graphs have a different number of cells. Naively copying that code doesn't seem to change the resulting graph dimensions for my case.

Here's another similar question:

The perils of aligning plots in ggplot

The question itself seems to suggest a good option, but rbind.gtable complains if the tables have different numbers of columns, which is the case here due to the legend. Perhaps there's a way to slot in an extra empty column in the second table? Or a way to suppress the legend in the first graph and then re-add it to the combined graph?

解决方案

Here's a solution that doesn't require explicit use of grid graphics. It uses facets, and hides the legend entry for "ratio" (using a technique from https://stackoverflow.com/a/21802022).

library(reshape2)

results_long <- melt(results, id.vars="index")
results_long$facet <- ifelse(results_long$variable=="ratio", "ratio", "values")
results_long$facet <- factor(results_long$facet, levels=c("values", "ratio"))

ggplot(results_long, aes(x=index, y=value, colour=variable)) +
  geom_point() +
  facet_grid(facet ~ ., scales="free_y") +
  scale_colour_manual(breaks=c("control","value"),
                      values=c("#1B9E77", "#D95F02", "#7570B3")) +
  theme(legend.justification=c(0,1), legend.position=c(0,1)) +
  guides(colour=guide_legend(title=NULL)) +
  theme(axis.title.y = element_blank())

这篇关于将多个ggplot图与有或没有图例对齐的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆