使用 R 和 ggplot2 绘制金字塔图
我需要画一个金字塔图,就像所附的那样.
I need to draw a pyramid plot, like the one attached.
我从 这里,谁能给我一些关于使用 ggplot 执行此操作的提示?谢谢!
I found an example using R (but not ggplot) from here, can anyone give me some hint on doing this using ggplot? Thanks!
这本质上是一个背靠背的条形图,类似于优秀学习者博客中使用 ggplot2
生成的那些:
This is essentially a back-to-back barplot, something like the ones generated using ggplot2
in the excellent learnr blog: http://learnr.wordpress.com/2009/09/24/ggplot2-back-to-back-bar-charts/
您可以将 coord_flip
与其中一个图一起使用,但我不确定如何让它像上面那样在两个图之间共享 y 轴标签.下面的代码应该让你足够接近原始代码:
You can use coord_flip
with one of those plots, but I'm not sure how you get it to share the y-axis labels between the two plots like what you have above. The code below should get you close enough to the original:
首先创建数据的示例数据框,将 Age 列转换为具有所需断点的因子:
First create a sample data frame of data, convert the Age column to a factor with the required break-points:
require(ggplot2)
df <- data.frame(Type = sample(c('Male', 'Female', 'Female'), 1000, replace=TRUE),
Age = sample(18:60, 1000, replace=TRUE))
AgesFactor <- ordered( cut(df$Age, breaks = c(18,seq(20,60,5)),
include.lowest = TRUE))
df$Age <- AgesFactor
现在开始构建图:使用相应的数据子集创建男性和女性图,抑制图例等.
Now start building the plot: create the male and female plots with the corresponding subset of the data, suppressing legends, etc.
gg <- ggplot(data = df, aes(x=Age))
gg.male <- gg +
geom_bar( subset = .(Type == 'Male'),
aes( y = ..count../sum(..count..), fill = Age)) +
scale_y_continuous('', formatter = 'percent') +
opts(legend.position = 'none') +
opts(axis.text.y = theme_blank(), axis.title.y = theme_blank()) +
opts(title = 'Male', plot.title = theme_text( size = 10) ) +
coord_flip()
对于女性情节,使用 trans = "reverse"
...
For the female plot, reverse the 'Percent' axis using trans = "reverse"
...
gg.female <- gg +
geom_bar( subset = .(Type == 'Female'),
aes( y = ..count../sum(..count..), fill = Age)) +
scale_y_continuous('', formatter = 'percent', trans = 'reverse') +
opts(legend.position = 'none') +
opts(axis.text.y = theme_blank(),
axis.title.y = theme_blank(),
title = 'Female') +
opts( plot.title = theme_text( size = 10) ) +
coord_flip()
现在创建一个绘图只是为了使用 geom_text
显示年龄括号,但也使用一个虚拟的 geom_bar
来确保年龄"轴的缩放比例情节与男性和女性情节中的相同:
Now create a plot just to display the age-brackets using geom_text
, but also use a dummy geom_bar
to ensure that the scaling of the "age" axis in this plot is identical to those in the male and female plots:
gg.ages <- gg +
geom_bar( subset = .(Type == 'Male'), aes( y = 0, fill = alpha('white',0))) +
geom_text( aes( y = 0, label = as.character(Age)), size = 3) +
coord_flip() +
opts(title = 'Ages',
legend.position = 'none' ,
axis.text.y = theme_blank(),
axis.title.y = theme_blank(),
axis.text.x = theme_blank(),
axis.ticks = theme_blank(),
plot.title = theme_text( size = 10))
最后,使用 Hadley Wickham 书中的方法在网格上排列图:
Finally, arrange the plots on a grid, using the method in Hadley Wickham's book:
grid.newpage()
pushViewport( viewport( layout = grid.layout(1,3, widths = c(.4,.2,.4))))
vplayout <- function(x, y) viewport(layout.pos.row = x, layout.pos.col = y)
print(gg.female, vp = vplayout(1,1))
print(gg.ages, vp = vplayout(1,2))
print(gg.male, vp = vplayout(1,3))