ggplo2 [R]

时间:2018-07-05 03:31:52

标签: r ggplot2 geom-bar

我正在尝试制作一个条形图,结合功能区/面积图,该图说明每个站的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:按模式将单独的木板/木板条分开 enter image description here

类型2:按模式堆叠的板/载条形图 enter image description here

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

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)

enter image description here

问题是:

类型1:
 -无法在标签为mrt的x轴上的brtmode之间留空格。我将澄清每种模式的区别。
 -x轴上的 interaction函数不能提供modekey的理想顺序。如第一点所述,mrt-onmrt-offbrt-onbrt-off是标签的最佳位置。 可以解决

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

常见问题
 -色带不是阶梯状 可以解决
 -色带未堆叠(position="stack"返回错误) 可以解决
 -色带使条形变得更不可见(也许可以通过alpha进行调整,但是可以设置前后关系更好) 可以解决

我不确定是否可以在ggplot2中进行这种调整,但是我会建议您获得理想的图形。
我还测试了其他一些示例,例如geom_step,但效果不佳。另一个问题是,如果我使用geom_area而不是geom_ribbon,则还会绘制存储在与volume相关的key==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 的示例 enter image description here

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


==更新==
我可以稍微更新一下图,如下所示: enter image description here

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

此外,有必要使用lag调整南行的旅客数量,如下所述:

Generate a Filled 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)

但是,我仍然遇到以下问题:

  • 酒吧的订单可以解决
  • 类型1中mode之间的空格
  • 类型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)

enter image description here

MRTBRT的小节之间的间隔可能有点复杂。 仍然欢迎对剩下的问题堆叠和分组的条形图提出建议。
据报道,@ Axeman不能同时进行堆叠和分组


==最终更新==
当我达到需要制作的脚本时,我将与您分享以下脚本: 但是,我仍然对scale_fill_manual的工作方式感到困惑。 valuesbreaks/labels的顺序彼此不对应。我只是根据结果进行了手动调整,如果您能提供一些建议使代码更好,我将不胜感激。

enter image description here

    ## 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()

0 个答案:

没有答案