ggplot2:将各个facet_wrap构面另存为独立的构图对象 [英] ggplot2: Save individual facet_wrap facets as separate plot objects
问题描述
我是 facet_wrap
的忠实粉丝。尽管分割一个大数据框并绘制几张图并在R内进行探索是快速的,但它并不总是在纸张或功率点上呈现的最佳工具。
我发现自己在缩放,binwidth和字体大小方面浪费了很多时间,并最终修改了绘图的空间。
有时我只是将我的数据框许多数据帧并为每一个单独绘制。稍后加入 multiplot
或手工加入他们。
我想知道是否有可能制作ggplot几乎是以相同的方式调用(一个大的df带有一个用于分面的因子列)或者一种使ggplot从类似列表的数据框中读取的方法,这些数据框由我的faceting因子分隔。理想的输出结果应该是多个单独的地块,我稍后会在inkscape中进行编辑(并使用 free_y
scale来减少痛苦)。
要清楚的是,
df <-mtcars
ggplot(df,aes(df $ mpg ,df $ disp,color = factor(cyl)))+
geom_point(aes(df $ mpg,df $ disp))+
facet_wrap(〜cyl)
产生一个图。在这种情况下,我希望的输出是三个图,每个方面一个。
您可以使用 lapply
为每个值 cyl
创建一个图表: <$ p $对于每个cyl值,创建一个单独的图,并将每个图存储在列表中。
p.list = lapply(sort(unique(mtcars $ cyl)),function(i) {
ggplot(mtcars [mtcars $ cyl == i,],aes(mpg,disp,color = factor(cyl)))+
geom_point(show.legend = FALSE)+
facet_wrap(〜cyl)+
scale_colour_manual(values = hcl(seq(15,365,length.out = 4)[match(i,sort(unique(mtcars $ cyl)))],100,65))
$复杂的
scale_colour_manual
参数如果 cyl
的所有值包含在对 ggplot 的单次调用中,则它们将以与着色相同的方式对点标记进行着色。 code>。
更新:要解决您的问题,请点击这里:
$ $ p $ code $#假数据
set.seed(15)
dat = data.frame(group = rep(c( A,B,C),每个= 100),
value = c(mapply(rnorm,100,c(5,10,20),c(1,3,5))) )
p.list = lapply(sort(unique(dat $ group)),function(i){
ggplot(dat [dat $ group == i,],aes(value ,fill = group))+
geom_histogram(show.legend = FALSE,color =grey20,binwidth = 1)+
facet_wrap(〜group)+
scale_fill_manual(values = hcl seq(15,365,length.out = 4)[match(i,sort(unique(dat $ group)))],100,65))+
scale_x_continuous(limits = range(dat $ value))+
theme_gray(base_size = 15)
})
结果如下。请注意,上面的代码在所有三个图表上给出了相同的x尺度,但y尺度不一样。为了获得相同的y值,你可以将它硬编码为 scale_y_continuous
。
#将所有三个图一起排列
library(gridExtra)
do.call(grid.arrange, c(p.list,nrow = 3))
I am a big fan of facet_wrap
. Though it is fast to split a big data frame and plot several plots and explore within R, it's not always the best tool for presenting in paper or power point.
I find myself wasting a lot of time with scales, binwidths and font sizes and ultimately modifying on inkscape the plot.
Sometimes I just subset my data frame into many data frames and plot individually for each one. Later join them with multiplot
or by hand.
I was wondering if there might be a way of making the ggplot call almost in the same way (one big df with a factor column used for faceting) or a way to make ggplot read from something with list-like data frame separated by my faceting factor. The ideal output should be multiple single plots which I'll edit later on inkscape (and use free_y
scales to make it less painful)
To be clear,
df<-mtcars
ggplot(df,aes(df$mpg,df$disp,color=factor(cyl)))+
geom_point(aes(df$mpg,df$disp))+
facet_wrap( ~cyl)
Produces one plot. My desired output in this case would be three plots, one for each facet.
You can use lapply
to create a list with one plot for each value of cyl
:
# Create a separate plot for each value of cyl, and store each plot in a list
p.list = lapply(sort(unique(mtcars$cyl)), function(i) {
ggplot(mtcars[mtcars$cyl==i,], aes(mpg, disp, colour=factor(cyl))) +
geom_point(show.legend=FALSE) +
facet_wrap(~cyl) +
scale_colour_manual(values=hcl(seq(15,365,length.out=4)[match(i, sort(unique(mtcars$cyl)))], 100, 65))
})
The complicated scale_colour_manual
argument is a way to color the point markers the same way they would be colored if all the values of cyl
were included in a single call to ggplot
.
UPDATE: To address your comments, how about this:
# Fake data
set.seed(15)
dat = data.frame(group=rep(c("A","B","C"), each=100),
value=c(mapply(rnorm, 100, c(5,10,20), c(1,3,5))))
p.list = lapply(sort(unique(dat$group)), function(i) {
ggplot(dat[dat$group==i,], aes(value, fill=group)) +
geom_histogram(show.legend=FALSE, colour="grey20", binwidth=1) +
facet_wrap(~group) +
scale_fill_manual(values=hcl(seq(15,365,length.out=4)[match(i, sort(unique(dat$group)))], 100, 65)) +
scale_x_continuous(limits=range(dat$value)) +
theme_gray(base_size=15)
})
The result is below. Note that the code above gives you the same x-scale on all three graphs, but not the same y-scale. To get the same y-scale, you can either hard-code it as, say, scale_y_continuous(limits = c(0,35))
, or you can find the maximum count programmatically for whatever binwidth you set, and then feed that to scale_y_continuous
.
# Arrange all three plots together
library(gridExtra)
do.call(grid.arrange, c(p.list, nrow=3))
这篇关于ggplot2:将各个facet_wrap构面另存为独立的构图对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!