首页 > 解决方案 > ggplo2 [R] 中复杂的上下车巴士乘客的多条和带状/区域图

问题描述

我正在尝试制作一个结合带状/区域图的条形图,该图说明每个车站的 BRT/MRT 线路的登机/下车乘客以及沿走廊方向的分段乘客量。

初始数据框如下所示:

df <- data.frame(
mode=c("mrt","mrt","mrt","mrt","mrt","mrt","mrt","mrt","mrt","mrt",
       "brt","brt","brt","brt","brt","brt","brt","brt","brt","brt"),
direction=c("Northbound","Northbound","Northbound","Northbound","Northbound",
            "Southbound","Southbound","Southbound","Southbound","Southbound",
            "Northbound","Northbound","Northbound","Northbound","Northbound",
            "Southbound","Southbound","Southbound","Southbound","Southbound"),
station=c("a","b","c","d","e","e","d","c","b","a","a","b","c","d","e","e","d","c","b","a"),
on=c(40,30,20,10,0,40,30,20,10,0,20,15,10,5,0,20,15,10,5,0),
off=c(0,10,20,30,40,0,10,20,30,40,0,5,10,15,20,0,5,10,15,20),
volume=c(40,60,60,40,0,40,60,60,40,0,20,30,30,20,0,20,30,30,20,0))

初始数据帧被转换为长格式ggplot2

library(tidyverse)
    df2 <- df %>% gather(key=key,value=trip,on,off) %>% mutate(
                station=factor(station,levels=c("a","b","c","d","e"),labels=c("a","b","c","d","e")),
                key=factor(key,levels=c("on","off"),labels=c("on","off")),
                direction=factor(direction,levels=c("Northbound","Southbound"),
                                           labels=c("Northbound","Southbound")),
                mode=factor(mode,levels=c("mrt","brt"),labels=c("mrt","brt")))

打印出来df2是这样的:

> df2
   mode  direction station volume key trip
1   mrt Northbound       a     40  on   40
2   mrt Northbound       b     60  on   30
3   mrt Northbound       c     60  on   20
4   mrt Northbound       d     40  on   10
5   mrt Northbound       e      0  on    0
6   mrt Southbound       e     40  on   40
7   mrt Southbound       d     60  on   30
8   mrt Southbound       c     60  on   20
9   mrt Southbound       b     40  on   10
10  mrt Southbound       a      0  on    0
11  brt Northbound       a     20  on   20
12  brt Northbound       b     30  on   15
13  brt Northbound       c     30  on   10
14  brt Northbound       d     20  on    5
15  brt Northbound       e      0  on    0
16  brt Southbound       e     20  on   20
17  brt Southbound       d     30  on   15
18  brt Southbound       c     30  on   10
19  brt Southbound       b     20  on    5
20  brt Southbound       a      0  on    0
21  mrt Northbound       a     40 off    0
22  mrt Northbound       b     60 off   10
23  mrt Northbound       c     60 off   20
24  mrt Northbound       d     40 off   30
25  mrt Northbound       e      0 off   40
26  mrt Southbound       e     40 off    0
27  mrt Southbound       d     60 off   10
28  mrt Southbound       c     60 off   20
29  mrt Southbound       b     40 off   30
30  mrt Southbound       a      0 off   40
31  brt Northbound       a     20 off    0
32  brt Northbound       b     30 off    5
33  brt Northbound       c     30 off   10
34  brt Northbound       d     20 off   15
35  brt Northbound       e      0 off   20
36  brt Southbound       e     20 off    0
37  brt Southbound       d     30 off    5
38  brt Southbound       c     30 off   10
39  brt Southbound       b     20 off   15
40  brt Southbound       a      0 off   20

我试图达到两种类型的输出:

类型 1:按模式分离板/亮条图 在此处输入图像描述

类型 2:按模式堆叠的板/点亮条形图 在此处输入图像描述

目前我可以通过以下脚本制作下图:

ggplot(df2,aes(x=station)) +
geom_bar(aes(y=trip,fill=interaction(mode,key)),stat="identity",
         position=position_dodge(preserve="single"),width=0.8) +
geom_ribbon(aes(ymin=0,ymax=volume,group=interaction(mode,key),fill=mode),alpha=0.2) +
facet_wrap(~direction,nrow=2)

在此处输入图像描述

问题是:

类型 1:
- 不能在标签为 的 x 轴之间mrt和中创建空白。我会澄清每种模式的区别。 - x 轴上的函数不提供和的理想顺序如第一点所述,, , ,是标签的最佳定位。可以解决的brtmode
interactionmodekeymrt-onmrt-offbrt-onbrt-off

类型 2:
- 无法制作分组和堆叠的条形图。

常见问题
-功能区不是阶梯形状 可以解决
-功能区没有堆叠(并position="stack"返回错误) 可以解决
-功能区使条不那么明显(也许可以调整,alpha但如果前后关系可以更好设置) 可以解决

我不确定是否可以进行这样的调整,ggplot2但我会听取您的建议以获得理想的图表。
我还测试了一些其他示例,例如geom_step但效果不佳。另一个问题是,如果我使用geom_area而不是,存储在相关字段中的geom_ribbon不必要值也会被绘制:volumekey==off

ggplot(df2,aes(x=station)) +
geom_bar(aes(y=trip,fill=interaction(mode,key)),stat="identity",
         position=position_dodge(preserve="single"),width=0.8) +
geom_area(aes(y=volume,group=interaction(mode,key),fill=interaction(mode,key)),position="stack") +
facet_wrap(~direction,nrow=2)

示例geom_area 在此处输入图像描述

我非常感谢您的建议,以获得我这几天试图产生的理想结果。


== 已更新 ==
我可以稍微更新下图,如下所示: 在此处输入图像描述

我使用geom_stepribbon了 ggplot2 的扩展: https ://cran.r-project.org/web/packages/RcmdrPlugin.KMggplot2/vignettes/geom-stepribbon.html

此外,有必要调整南行的客流量,lag如下所述:

生成填充的 geom_step

## Prepare df for geom_stepribbon [it requires some more packages]
df3 <- df2 %>% group_by(direction) %>%
    mutate_at(vars(volume),funs(ifelse(direction=="Southbound",lag(volume),.))) %>% data.frame()

## Plot
ggplot(df3,aes(x=station)) +
geom_stepribbon(aes(ymin=0,ymax=volume,group=mode,fill=mode),alpha=0.5) +
geom_bar(aes(y=trip,fill=interaction(mode,key)),stat="identity",
         position=position_dodge(preserve="single"),width=0.8) +
facet_wrap(~direction,nrow=2)

但是,我仍然有以下问题:

进一步的建议表示赞赏。

== 已更新版本 2== 通过在以下脚本中手动更改因子级别来解决柱线顺序的
剩余问题。

ggplot(df5,aes(x=station)) +
geom_stepribbon(aes(ymin=0,ymax=volume,group=mode,fill=mode),alpha=0.5) +
geom_bar(aes(y=trip,fill=factor(interaction(mode,key),
                    levels=c("mrt.on","mrt.off","brt.on","brt.off"),
                    labels=c("MRT-Board","MRT-Alight","BRT-Board","BRT-Alight"))),
                    stat="identity", position=position_dodge(preserve="single"),width=0.8) +
facet_wrap(~direction,nrow=2)

在此处输入图像描述

也许 和 条之间的空间MRT有点BRT复杂。仍然欢迎对 剩余问题、堆叠和分组条提出建议。
据报道,@Axeman 不可能同时进行堆叠和分组


==最终更新==
因为我可以达到我需要制作的那个,我将在此分享脚本:但是,我仍然对如何scale_fill_manual工作感到困惑。的顺序valuesbreaks/labels彼此不对应。我只是根据结果手动调整它,如果您能提供任何建议以使代码更好,我将不胜感激。

在此处输入图像描述

    ## Set year
        year <- 18

    ## df5 corresponds to df3 in the previous update
        ## Maximum passenger
        max.mrt.n <- df5 %>% filter(mode=="mrt" & direction=="Northbound") %>%
                             summarize(max=max(volume)) %>% as.integer()
        max.mrt.s <- df5 %>% filter(mode=="mrt" & direction=="Southbound") %>%
                             summarize(max=max(volume)) %>% as.integer()
        max.brt.n <- df5 %>% filter(mode=="brt" & direction=="Northbound") %>%
                             summarize(max=max(volume)) %>% as.integer()
        max.brt.s <- df5 %>% filter(mode=="brt" & direction=="Southbound") %>%
                             summarize(max=max(volume)) %>% as.integer()
        max.mrt <- data.frame(direction=c("Northbound","Southbound"),label=c(max.mrt.n,max.mrt.s))
        max.brt <- data.frame(direction=c("Northbound","Southbound"),label=c(max.brt.n,max.brt.s))

        ## Set print window
        png("CorridorPax.png",height=720, width=960, res=144)
        ## Specify data frame and x-axis
        g <- ggplot(df5,aes(x=station)) +
        ## Draw step ribbon chart
        geom_stepribbon(aes(ymin=0,ymax=volume,
                        group=factor(mode,levels=c("mrt","brt"),labels=c("MRT Pax.","BRT Pax.")),
                        fill=factor(mode,levels=c("mrt","brt"),labels=c("MRT Pax.","BRT Pax."))),
                        alpha=0.4) +
        ## Draw bar chart
        geom_bar(aes(y=trip,fill=factor(interaction(mode,key),
                            levels=c("mrt.on","mrt.off","brt.on","brt.off"),
                            labels=c("MRT-Board","MRT-Alight","BRT-Board","BRT-Alight"))),
                            stat="identity", position=position_dodge(preserve="single"),width=0.8) +
        ## Facet by direction
        facet_wrap(~direction,nrow=2) +
        ## Appearance
            ## Title and xy-axis
            ggtitle(paste0("Passenger volume of MRT and BRT along the corridor in 20",year)) +
            xlab("Station") +
            ylab("Number of Daily Passengers ('000)") +
            ## Theme
            theme_bw() +
            ## Rotate label and adjust font size
            theme(title=element_text(size=10),
                  axis.title=element_text(size=10),
                  axis.text.x=element_text(angle=90,hjust=1,vjust=0.25,size=10),
                  axis.text.y=element_text(size=8),
                  legend.text=element_text(size=8)
                  ) +
            ## Limit and breaks of y-axis
            scale_y_continuous(breaks=seq(0,60,by=5),limits=c(0,60)) +
            ## Legend
            scale_fill_manual(name="Passenger",
                              values=c("cadetblue2","darkorange","gold",
                                       "royalblue","firebrick","lawngreen"),
                              breaks=c("MRT Pax.","BRT Pax.","MRT-Board","MRT-Alight","BRT-Board","BRT-Alight"),
                              labels=c("MRT Pax.","BRT Pax.",                                  "MRT-Board","MRT-Alight","BRT-Board","BRT-Alight")) +
            ## Maximum load
            geom_text(mapping=aes(x=Inf,y=Inf,
                      label="Maximum sectional load (1,000 pax/day)",vjust=1.3,hjust=1.02),size=3) +
            geom_text(data=max.mrt,mapping=aes(x=Inf,y=Inf,
                      label=paste0("MRT=",label)), vjust=2.6,hjust=2.4,size=3) +
            geom_text(data=max.brt,mapping=aes(x=Inf,y=Inf,
                      label=paste0("BRT=",label)), vjust=2.6,hjust=1.2,size=3)
        ## Export png
        print(g)
        ## Close printing window
        dev.off()

标签: rggplot2geom-bar

解决方案


推荐阅读