【R画图学习9.2】双坐标轴柱线图

今天我们学习画柱状图的另一个技巧,如何绘制双坐标系。一般情况下包含多组数据,还这多组数据的scale或者单位又不太一样,所以有时候就需要多坐标系来实现。

比如上面这张图,为了在一张图中展示更丰富的信息,既有柱状图又有折线图。

如果柱状图和折线图的值域不一致,比如柱状图表示的是数量,折线图表示累计百分比,当二者出现在一张图中的时候,值域范围 [0, 1] 折线图就会几乎贴近 x 轴而失去意义。

这时候我们就建立两个坐标轴,柱状图和折线图各自使用各自的scale。

比如,我们生成下面的测试数据:

data <- data.frame(group = c("<10", "10-15", "15-20", "20-25", "25-30", ">30"),

                  count = c(70, 15, 8, 4, 2, 1),

                  percent = c(0.70, 0.85, 0.93, 0.97, 0.99, 1.00))

# 把group变成factor,从而按照我们想显示的顺序显示

data$group <- factor(data$group,levels = as.character(data$group))

ggplot(data) +

geom_bar(aes(x = group, y = count), stat = "identity", fill = '#168aad')

上面就是生成了一个非常简单的柱状图。

但是,下面如果我们添加线图的话:

ggplot(data) +

geom_bar(aes(x = group, y = count), stat = "identity", fill = '#168aad')+

geom_line(aes(x = group, y = percent), size = 1, color = '#800080') +

geom_point(aes(x = group, y = percent), size = 3, shape = 19, color='#800080')

就会报错:

geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?

查资料,说要把group设置成1,尤其是有多组变量的时候。

ggplot(data) +

geom_bar(aes(x = group, y = count), stat = "identity", fill = '#168aad')+

geom_line(aes(x = group, y = percent), size = 1, color = '#800080',group=1) +

geom_point(aes(x = group, y = percent), size = 3, shape = 19, color='#800080',group=1)

但是效果如下图,因为count和percentage scale是不一样的,所以percentage的规律其实是被完全覆盖掉的。

所以,如果我们要想让count和percent分别按照自己的值域范围显示,并且呈现在同一个图中,就需要把其中之一的值域范围向另一个做投影,以统一值域范围,相当于 scaling。

这里我们选择将percent向count做投影,投影之后新增一列percent2,然后通过改变坐标轴 label 的方式达到保持原指标值域范围的目的。

data$percent2 = data$percent / max(data$percent) * max(data$count)

ggplot(data) +

geom_bar(aes(x = group, y = count), stat = "identity", fill = '#168aad')+

geom_line(aes(x = group, y = percent2), size = 1, color = '#800080',group=1) +

geom_point(aes(x = group, y = percent2), size = 3, shape = 19, color='#800080',group=1)

这样把count和percentage放在一个scale区间内,规律就比较能展现出来了。

下面,我们尝试来添加percentage的坐标系。

主要通过scale_y_continuous函数里面的sec.axis参数来实现创制2个坐标系。

data$percent2 = data$percent / max(data$percent) * max(data$count)

count_max=max(data$count)

label=paste0(seq(0, 100, 10))


ggplot(data) +

geom_bar(aes(x = group, y = count), stat = "identity", fill = '#168aad')+

geom_line(aes(x = group, y = percent2), size = 1, color = '#800080',group=1) +

geom_point(aes(x = group, y = percent2), size = 3, shape = 19, color='#800080',group=1)+

#geom_text(aes(x=group,y=count,label=count),size=5,color="red")+

scale_y_continuous(

limits=c(0,count_max),

breaks=seq(0,count_max,5),

sec.axis = sec_axis(~./0.99, name = "percent(%)",

breaks = seq(0,count_max,count_max/10),

labels = label)

)

通过sec.axis添加次级y轴,次级y轴的刻度需要通过一级y轴的刻度调整而来,~./0.99就表示次级y轴的范围是用一级y轴除以0.99

然后,我们再来调整一下外观。

ggplot(data) +

geom_bar(aes(x = group, y = count), stat = "identity", fill = '#168aad')+

geom_line(aes(x = group, y = percent2), size = 1, color = '#800080',group=1) +

geom_point(aes(x = group, y = percent2), size = 3, shape = 19, color='#800080',group=1)+

#geom_text(aes(x=group,y=count,label=count),size=5,color="red")+

scale_y_continuous(

limits=c(0,count_max),

breaks=seq(0,count_max,5),

sec.axis = sec_axis(~./0.99, name = "percent(%)",

breaks = seq(0,count_max,count_max/10),

labels = label)

)+

theme_classic()+

#theme_minimal() +

theme(panel.grid.major.x = element_blank(),

          panel.grid.minor.x = element_blank(),

          panel.grid.major.y = element_blank(),

          panel.grid.minor.y = element_blank()) +

theme(plot.title = element_text(hjust = 0.5)) +

labs(title = paste0("CV% distribution"), x = "group", y = "count")+

theme(text = element_text(size = 15))+

theme(axis.line.x = element_line(linetype = 1, color = "darkblue", size = 1),

      axis.line.y = element_line(linetype = 1, color = "darkblue", size = 1),

      axis.ticks.x = element_line(color = "darkblue", size = 1),

      axis.ticks.y = element_line(color = "darkblue", size = 1),

          )

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,390评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,821评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,632评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,170评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,033评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,098评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,511评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,204评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,479评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,572评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,341评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,893评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,171评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,486评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,676评论 2 335

推荐阅读更多精彩内容