为R金字塔图

时间:2017-10-26 11:57:52

标签: r

请帮我在R金字塔图中添加平滑线条(图中所示的粗黑线),如附图所示。感谢您的帮助。This plot shows the population distribution according to the age and gender

xy.pop<-c(3.2,3.5,3.6,3.6,3.5,3.5,3.9,3.7,3.9,3.5,3.2,2.8,2.2,1.8,1.5,1.3,0.7,0.4)
xx.pop<-c(3.2,3.4,3.5,3.5,3.5,3.7,4,3.8,3.9,3.6,3.2,2.5,2,1.7,1.5,1.3,1,0.8)
agelabels<-c("0-4","5-9","10-14","15-19","20-24","25-29","30-34",
         "35-39","40-44","45-49","50-54","55-59","60-64","65-69","70-74",
         "75-79","80-44","85+")
mcol<-color.gradient(c(0,0,0.5,1),c(0,0,0.5,1),c(1,1,0.5,1),18)
fcol<-color.gradient(c(1,1,0.5,1),c(0.5,0.5,0.5,1),c(0.5,0.5,0.5,1),18)
par(mar=pyramid.plot(xy.pop,xx.pop,labels=agelabels,main="Australian population pyramid 2002",lxcol=mcol,rxcol=fcol,))

2 个答案:

答案 0 :(得分:6)

以下内容(使用ggplot而非基础R图形)。

# Your data
xy.pop<-c(3.2,3.5,3.6,3.6,3.5,3.5,3.9,3.7,3.9,3.5,3.2,2.8,2.2,1.8,1.5,1.3,0.7,0.4)
xx.pop<-c(3.2,3.4,3.5,3.5,3.5,3.7,4,3.8,3.9,3.6,3.2,2.5,2,1.7,1.5,1.3,1,0.8)
agelabels<-c("0-4","5-9","10-14","15-19","20-24","25-29","30-34",
            "35-39","40-44","45-49","50-54","55-59","60-64","65-69","70-74",
            "75-79","80-44","85+")

# Collect data in dataframe
df <- rbind.data.frame(
    cbind.data.frame(Percentage = -xy.pop, Group = agelabels, Gender = "male"),
    cbind.data.frame(Percentage = +xx.pop, Group = agelabels, Gender = "female"));

# Make sure agelabels have the right order
df$Group <- factor(df$Group, levels = agelabels);

# (gg)plot
gg <- ggplot(
    data = df, 
    aes(x = Group, y = Percentage, fill = Gender, group = Gender));
gg <- gg + geom_bar(data = subset(df, Gender == "female"), stat = "identity");
gg <- gg + geom_bar(data = subset(df, Gender == "male"), stat = "identity");
gg <- gg + coord_flip();
gg <- gg + geom_smooth(
    colour = "black", method = "loess", se = FALSE, show.legend = FALSE, size = 0.5);
gg <- gg + labs(
    x = "Age", 
    y = "Percentage", 
    title = "Australian population pyramid 2012");
gg <- gg + scale_y_continuous(
    breaks = seq(-4, 4, by = 2), 
    labels = c(rev(seq(0, 4, by = 2)), seq(2, 4, by = 2)));
print(gg);

enter image description here

我在这里将LOESS曲线分别与男性和女性金字塔两半相配合(通过group美学)。

它与你展示的情节不完全相同,但仍有改进/调整的空间。例如,您可以更改fill美学以实现条形的百分比相关填充。

信用到期的信用:此解决方案基于@DidzisElferts的this post

更新(近一年后)

我一直想查看这个答案,以便将ggplot2解决方案的审美相似性与plotrix::pyramid.plot生成的情节相提并论。这是一个非常接近的更新。

# Define function to draw the left/right half of an age pyramid
ggpyramidhalf <- function(df, pos = "left", title) {
    gg <- ggplot(df, aes(Group, Percentage, group = Gender)) +
        geom_col(aes(fill = Group), colour = "black") +
        geom_smooth(
            colour = "black",
            method = "loess",
            se = F,
            show.legend = F, size = 0.5) +
        theme_minimal() +
        labs(y = "%", title = title) +
        coord_flip(expand = FALSE) +
        theme(
            axis.title.y = element_blank(),
            panel.grid.major = element_blank(),
            panel.grid.minor = element_blank())
    if (pos == "left") {
        gg <- gg +
            ylim(c(min(range(pretty(df$Percentage))), 0)) +
            scale_fill_manual(
                values = colorRampPalette(c("blue", "white"))(length(agelabels)),
                guide = F) +
            theme(
                plot.title = element_text(hjust = 1),
                axis.text.y = element_blank())
    } else {
        gg <- gg +
            ylim(c(0, max(range(pretty(df$Percentage))))) +
            scale_fill_manual(
                values = colorRampPalette(c("red", "white"))(length(agelabels)),
                guide = F) +
            theme(
                plot.title = element_text(hjust = 0),
                axis.title.y = element_blank(),
                axis.text.y = element_text(hjust = 0.5, margin = margin(r = 10)))
    }
    gg
}

# Draw left (male) half of age pyramid
gg1 <- df %>%
    filter(Gender == "male") %>%
    mutate(Group = factor(Group, agelabels)) %>%
    ggpyramidhalf(pos = "left", title = "Male")

# Draw right (female) half of age pyramid
gg2 <- df %>%
    filter(Gender == "female") %>%
    mutate(Group = factor(Group, agelabels)) %>%
    ggpyramidhalf(pos = "right", title = "Female")

# Use gridExtra to draw both halfs in one plot
library(gridExtra)
library(grid)
grid.arrange(
    gg1, gg2,
    ncol = 2,
    widths = c(1, 1.15),
    top = textGrob("Australian population period 2002", gp = gpar(font = 2)))

enter image description here

答案 1 :(得分:2)

以下是使用pyramid.plot的{​​{1}}函数的解决方案:

plotrix

enter image description here