一场用R语言打造的商务图表视觉盛宴
之前已经模仿了挺多网络上流行的高难度商务图表案例,自觉功力有所小成,就想着趁热打铁,把那些剩余的还没有被挖掘出来了的商务图表案例全部补全。
本篇给出不等宽柱形图案例以及MEKKO(也称市场细分矩阵)图案例全部四张图的R语言代码,作为ggplot商务图表进阶道路上的一个小小一步。
因素需要构造自定义标度,这里需要scale包的支持
library(ggplot2)
library(scales)
构造不等宽柱形图的案例数据(本案例模仿对象是刘万祥老师的《Excel图表之道》,感谢老师在业界的无私奉献精神,给我后备爱或者留下了如此丰富的图表案例资源,这里再次向老师致敬!)。
mydata<-data.frame(Name=paste0("项目",1:5),Scale=c(35,30,20,10,5),ARPU=c(56,37,63,57,59))
因为本篇 所构造的不等宽柱形图、MEKKO矩阵图等都是建立在四边形(或者呈为矩阵)的基础图形之上的,即物理的二维空间中,四个点坐标可以定位出一个四边形,利用R语言的向量化操作,就可以同时操纵n组长度为4的向量,来批量生成矩形块,这里的核心技巧只是在数据源中准确的生成每一组向量(也即每一个矩形块的水平轴起点、终点、垂直轴的起点、终点)。
在ggplot系统中,生成矩形的图层函数是geom_rect()函数,内置四个参数:
xmin\xmax\ymin\ymax
不等宽柱形图:
#构造矩形X轴的起点(最小点)
mydata$xmin<-0
for (i in 2:5){
mydata$xmin[i]<-sum(mydata$Scale[1:i-1])
}
#构造矩形X轴的终点(最大点)
for (i in 1:5){
mydata$xmax[i]<-sum(mydata$Scale[1:i])
}
#构造数据标签的横坐标:
for (i in 1:5){
mydata$label[i]<-sum(mydata$Scale[1:i])-mydata$Scale[i]/2
}
定义字体:
windowsFonts(myFont = windowsFont("微软雅黑"))
运行ggplot函数:
ggplot(mydata)+
geom_rect(aes(xmin=xmin,xmax=xmax,ymin=0,ymax=ARPU,fill=Name))+
scale_fill_manual(values=c("#54576B","#BD1F12","#E8BA11","#62962A","#9B56AF"))+
geom_text(aes(x=label,y=ARPU-3,label=ARPU),size=6,col="white",family="myFont")+
geom_text(aes(x=label,y=-2.5,label=Scale),size=4,col="black",family="myFont")+
geom_text(aes(x=label,y=-5.5,label=Name),size=4,col="black",family="myFont")+
annotate("text",x=16,y=70,label="不等宽柱形图",size=8,family="myFont")+
annotate("text",x=14,y=64,label="这是一幅很用心的图表",size=4,family="myFont")+
annotate("text",x=11,y=-9.8,label="Source:EasyCharts",size=4,family="myFont")+
ylim(-10,80)+
theme_nothing()
-----------------------------------------------------------------------------------------------------------
不等宽条形图:
该案例来自于本人小号数据小魔方,也曾在本平台转发过:
图表案例——全球创新国家1000强研发投入变动趋势
设置目录导入数据
mydata<-read.csv("barchart.csv",stringsAsFactors = FALSE)
names(mydata)[1:5]<-c("State","RD","Betw","Cumcost","class")
#构造矩形X轴的起点(最小点)
mydata$xmin<-0
for (i in 2:nrow(mydata)){
mydata$xmin[i]<-sum(mydata$RD[1:i-1])
}
#构造矩形X轴的终点(最大点)
for (i in 1:nrow(mydata)){
mydata$xmax[i]<-sum(mydata$RD[1:i])
}
#构造数据标签的横坐标:
for (i in 1:nrow(mydata)){
mydata$label[i]<-sum(mydata$RD[1:i])-mydata$RD[i]/2
}
mydata$class<-factor(mydata$class,levels=c("亚洲","欧洲","北美","其他地区")).
运行作图函数:
ggplot(mydata)+
geom_rect(aes(xmin=xmin,xmax=xmax,ymin=0,ymax=Betw,fill=class),col="white")+
coord_flip()+
scale_x_reverse()+
scale_y_continuous(limits=c(-.45,.7),breaks=seq(-.4,.7,.1),labels=percent_format(),position = "top")+
scale_fill_manual(values=c("#802428","#AB6661","#D1A6A1","#A89B94"))+
geom_text(aes(x=label,y=Betw/2,label=Betw),size=3,col="white",family="myFont")+
geom_text(aes(x=label,y=ifelse(Betw>0,Betw+.03,Betw-.033),label=mydata$RD),size=4,col="black",family="myFont")+
geom_text(aes(x=label,y=ifelse(Betw>0,-.07,.07),label=State),size=4,col="black",family="myFont")+
labs(title="不等宽柱形图",subtitle="这是一幅很用心的图表",caption="Source:EasyCharts",x="",y="")+
theme(
text=element_text(family="myFont"),
plot.title=element_text(size=18),
plot.subtitle=element_text(size=14),
plot.caption=element_text(size=10,hjust=0),
plot.background=element_blank(),
panel.background=element_blank(),
panel.grid=element_blank(),
axis.text.y=element_blank(),
axis.ticks.y=element_blank(),
legend.position=c(0.9,0.2),
axis.line.x=element_line()
)
![]()
--------------------------------------------------------------------------------------------------------
MEKKO(也称市场细分矩阵)
该图表同样来源于刘老师的图表宝典——《Excel图表之道》
Mekko<-read.csv("Mekko.csv",stringsAsFactors = FALSE)
Mekko$Class<-factor(Mekko$Class,order=T)
#构造矩形(Obama)X轴的起点(最小点)
Mekko$xmin<-0
for (i in 2:nrow(Mekko)){
Mekko$xmin[i]<-sum(Mekko$percent[1:i-1])
}
#构造矩形(Obama)X轴的终点(最大点)
for (i in 1:nrow(Mekko)){
Mekko$xmax[i]<-sum(Mekko$percent[1:i])
}
#构造数据标签的横坐标:
for (i in 1:nrow(Mekko)){
Mekko$label[i]<-sum(Mekko$percent[1:i])-Mekko$percent[i]/2
}
这里我不想重复映射两次geom_rect()图层函数,所以从新整理了数据源,一定要记得ggplot的作图体系中使用因子变量进行分类作图的思想,这里完全可以用一个类别标量赋给fill属性,避免代码冗余。
mynewdata1<-Mekko[,c(1,6,7)];mynewdata1$ymin<-0;mynewdata1$ymax<-Mekko$Obama;mynewdata1$Type<-"Obama"
mynewdata2<-Mekko[,c(1,6,7)];mynewdata2$ymin<-Mekko$Obama+Mekko$m;mynewdata2$ymax<-Mekko$Obama+Mekko$m+Mekko$McCain;mynewdata2$Type<-"McCain"
mynewdata<-rbind(mynewdata1,mynewdata2)
mynewdata$Type<-factor(mynewdata$Type,levels=c("Obama","McCain"),order=T)
运行作图函数:
ggplot(mynewdata)+
geom_rect(aes(xmin=xmin,xmax=xmax,ymin=ymin,ymax=ymax,fill=Type),col="white")+
scale_fill_manual(values=c("#004C7F","#B70023"))+
scale_x_continuous(breaks=Mekko$label,labels=Mekko$Class)+
geom_text(data=Mekko,aes(x=label,y=.25,label=percent(Obama)),size=3.5,col="white",family="myFont")+
geom_text(data=Mekko,aes(x=label,y=.8,label=percent(McCain)),size=3.5,col="white",family="myFont")+
labs(title="MEKKO-市场细分矩阵图",subtitle="这是一幅用心良苦的图表",caption="Source:EasyCharts",x="",y="")+
theme(
plot.margin=unit(c(2,0,0.5,0),"lines"),
panel.spacing=unit(c(0,0,0,0),"lines"),
axis.text.x=element_text(angle=90,size=10),
panel.background=element_blank(),
axis.ticks=element_blank(),
axis.text.y=element_blank(),
legend.position=c(.78,1),
legend.direction="horizontal",
text=element_text(family="myFont"),
plot.title=element_text(size=18),
plot.subtitle=element_text(size=14),
plot.caption=element_text(size=10,hjust=0),
legend.title=element_blank()
)
![]()
---------------------------------------------------------------------------------------------------------
ggplot(mynewdata)+
geom_rect(aes(xmin=xmin,xmax=xmax,ymin=ymin,ymax=ymax,fill=Type),col="white")+
coord_flip()+
scale_fill_manual(values=c("#004C7F","#B70023"))+
scale_x_continuous(breaks=Mekko$label,labels=Mekko$Class)+
geom_text(data=Mekko,aes(x=label,y=.25,label=percent(Obama)),size=3.5,col="white",family="myFont")+
geom_text(data=Mekko,aes(x=label,y=.8,label=percent(McCain)),size=3.5,col="white",family="myFont")+
labs(title="MEKKO-市场细分矩阵图",subtitle="这是一幅用心良苦的图表",caption="Source:EasyCharts",x="",y="")+
theme(
plot.margin=unit(c(0,0,0,0),"lines"),
panel.spacing=unit(c(0,0,0,0),"lines"),
axis.text.y=element_text(size=10),
panel.background=element_blank(),
axis.ticks=element_blank(),
axis.text.x=element_blank(),
legend.position=c(.78,1),
legend.direction="horizontal",
text=element_text(family="myFont"),
plot.title=element_text(size=18),
plot.subtitle=element_text(size=14),
plot.caption=element_text(size=10,hjust=0),
legend.title=element_blank()
)
![]()
因水平有限,代码写的比较糟糕,图表如有可改善的细节,还请的各位多多指点。
数据分析咨询请扫描二维码
若不方便扫码,搜微信号:CDAshujufenxi
数据分析在当今信息时代发挥着重要作用。单因素方差分析(One-Way ANOVA)是一种关键的统计方法,用于比较三个或更多独立样本组 ...
2025-04-25CDA持证人简介: 居瑜 ,CDA一级持证人国企财务经理,13年财务管理运营经验,在数据分析就业和实践经验方面有着丰富的积累和经 ...
2025-04-25在当今数字化时代,数据分析师的重要性与日俱增。但许多人在踏上这条职业道路时,往往充满疑惑: 如何成为一名数据分析师?成为 ...
2025-04-24以下的文章内容来源于刘静老师的专栏,如果您想阅读专栏《刘静:10大业务分析模型突破业务瓶颈》,点击下方链接 https://edu.cda ...
2025-04-23大咖简介: 刘凯,CDA大咖汇特邀讲师,DAMA中国分会理事,香港金管局特聘数据管理专家,拥有丰富的行业经验。本文将从数据要素 ...
2025-04-22CDA持证人简介 刘伟,美国 NAU 大学计算机信息技术硕士, CDA数据分析师三级持证人,现任职于江苏宝应农商银行数据治理岗。 学 ...
2025-04-21持证人简介:贺渲雯 ,CDA 数据分析师一级持证人,互联网行业数据分析师 今天我将为大家带来一个关于用户私域用户质量数据分析 ...
2025-04-18一、CDA持证人介绍 在数字化浪潮席卷商业领域的当下,数据分析已成为企业发展的关键驱动力。为助力大家深入了解数据分析在电商行 ...
2025-04-17CDA持证人简介:居瑜 ,CDA一级持证人,国企财务经理,13年财务管理运营经验,在数据分析实践方面积累了丰富的行业经验。 一、 ...
2025-04-16持证人简介: CDA持证人刘凌峰,CDA L1持证人,微软认证讲师(MCT)金山办公最有价值专家(KVP),工信部高级项目管理师,拥有 ...
2025-04-15持证人简介:CDA持证人黄葛英,ICF国际教练联盟认证教练,前字节跳动销售主管,拥有丰富的行业经验。在实际生活中,我们可能会 ...
2025-04-14在 Python 编程学习与实践中,Anaconda 是一款极为重要的工具。它作为一个开源的 Python 发行版本,集成了众多常用的科学计算库 ...
2025-04-14随着大数据时代的深入发展,数据运营成为企业不可或缺的岗位之一。这个职位的核心是通过收集、整理和分析数据,帮助企业做出科 ...
2025-04-11持证人简介:CDA持证人黄葛英,ICF国际教练联盟认证教练,前字节跳动销售主管,拥有丰富的行业经验。 本次分享我将以教培行业为 ...
2025-04-11近日《2025中国城市长租市场发展蓝皮书》(下称《蓝皮书》)正式发布。《蓝皮书》指出,当前我国城市住房正经历从“增量扩张”向 ...
2025-04-10在数字化时代的浪潮中,数据已经成为企业决策和运营的核心。每一位客户,每一次交易,都承载着丰富的信息和价值。 如何在海量客 ...
2025-04-09数据是数字化的基础。随着工业4.0的推进,企业生产运作过程中的在线数据变得更加丰富;而互联网、新零售等C端应用的丰富多彩,产 ...
2025-04-094月7日,美国关税政策对全球金融市场的冲击仍在肆虐,周一亚市早盘,美股股指、原油期货、加密货币、贵金属等资产齐齐重挫,市场 ...
2025-04-08背景 3月26日,科技圈迎来一则重磅消息,苹果公司宣布向浙江大学捐赠 3000 万元人民币,用于支持编程教育。 这一举措并非偶然, ...
2025-04-07在当今数据驱动的时代,数据分析能力备受青睐,数据分析能力频繁出现在岗位需求的描述中,不分岗位的任职要求中,会特意标出“熟 ...
2025-04-03