R语言:ggplot2精细化绘图——以实用商业化图表绘图为例(转)

本文旨在介绍R语言中ggplot2包的一些精细化操作,主要适用于对R画图有一定了解,需要更精细化作图的人,尤其是那些刚从excel转ggplot2的各位,有比较频繁的作图需求的人。不讨论那些样式非常酷炫的图表,以实用的商业化图表为主。包括以下结构:

1、画图前的准备:自定义ggplot2格式刷 
2、画图前的准备:数据塑形利器dplyr / tidyr介绍 
3、常用的商业用图:

    1)简单柱形图+文本(单一变量) 
    2)分面柱形图(facet_wrap/facet_grid) 
    3)簇型柱形图(position=”dodge”) 
    4)堆积柱形图(需要先添加百分比,再对百分比的变量做柱形图) 
    5)饼图、极坐标图 
    6)多重线性图

前言

这篇文章其实是我之前那篇博文的一个延续。因为接了一个活要用R定制化数据报表,其中涉及大量的对图表精雕细琢的工作。在深入研究ggplot2时,深深感觉到用ggplot2画图与用excel画图的不一样。

如果要用ggplot2画图,还是需要了解很多技术细节的。这些细节要么散落在R可视化技术和ggplot2:数据分析与图表技术这两本书里,要么散落在网上。因此在这里以我学习和总结的过程,对ggplot2的精细化画图做一个阐述,介绍我整理后的作图理念。

如果有进一步学习需要的各位,请直接买书或者自己实践学习。很多技术细节需要自己摸索才知道的,祝大家好运。

 

1、画图前的准备:自定义ggplot2格式刷

在画图前,我们首先定义一下ggplot2格式刷。

首先,ggplot2本身自带了很漂亮的主题格式,如theme_gray和theme_bw。但是在工作用图上,很多公司对图表格式配色字体等均有明文的规定。像我们公司,对主色、辅色、字体等都有严格的规定。如刘万祥老师早期的一篇配色博文里,大家更是可以看到,很多商业杂志的图表,配色风格都是非常相近的。因此,修改主题,使其更加适合我们的商业需求,保持图表风格统一,是非常必要的。

虽然ggplot2可以通过代码的追加,细细修改表距、背景色以及字体等框架。但是如果每做一个图,都要如此细调,代码将会非常繁琐,而且万一老板突然兴起要换风格时,代码修改将会非常痛苦。

幸运的是,ggplot2允许我们事先定制好图表样式,我们可以生成如mytheme或者myline这样的有明确配色主题的对象,到时候就像excel的定制保存图表模板或者格式刷,直接在生成的图表里引用格式刷型的主题配色,就可以快捷方便的更改图表内容,保持风格的统一了。

在运行之前,首先加载相关包

library(ggplot2)
library(dplyr)
library(ColorBrewer)
library(tidyr)
library(grid)
#载入格式刷
######

#定义好字体
windowsFonts(CA=windowsFont("Calibri"))

接下来是一个示范。我首先共享了我常用的一个主题刷,配色参考以下:

主体色:蓝色 085A9C ,红色 EF0808,灰色 526373 
辅助色:浅黄色 FFFFE7,橙色 FF9418, 绿色 219431, 明黄色 FF9418,紫色 9C52AD

定制了mytheme, myline_blue, mycolour等多个对象:

#定义好字体
windowsFonts(CA=windowsFont("Calibri"))
#事先定制好要加图形的形状、颜色、主题等
#定制主题,要求背景全白,没有边框。然后所有的字体都是某某颜色
#定制主题,要求背景全白,没有边框。然后所有的字体都是某某颜色
mytheme<-theme_bw()+theme(legend.position="top",
                         panel.border=element_blank(),
                         panel.grid.major=element_line(linetype="dashed"),
                         panel.grid.minor=element_blank(),
                         plot.title=element_text(size=15,
                                                 colour="#003087",
                                                 family="CA"),
                         legend.text=element_text(size=9,colour="#003087",
                                                  family="CA"),
                         legend.key=element_blank(),
                         axis.text=element_text(size=10,colour="#003087",
                                                family="CA"),
                         strip.text=element_text(size=12,colour="#EF0808",
                                                 family="CA"),
                         strip.background=element_blank()

                       )
pie_theme=mytheme+theme(axis.text=element_blank(),
                       axis.ticks=element_blank(),
                       axis.title=element_blank(),
                       panel.grid.major=element_blank())
#定制线的大小
myline_blue<-geom_line(colour="#085A9C",size=2)
myline_red<-geom_line(colour="#EF0808",size=2)
myarea=geom_area(colour=NA,fill="#003087",alpha=.2)
mypoint=geom_point(size=3,shape=21,colour="#003087",fill="white")
mybar=geom_bar(fill="#0C8DC4",stat="identity")
#然后是配色,考虑到样本的多样性,可以事先设定颜色,如3种颜色或7种颜色的组合
mycolour_3<-scale_fill_manual(values=c("#085A9C","#EF0808","#526373"))
mycolour_7<-scale_fill_manual(values=c("#085A9C","#EF0808","#526373",
"#FFFFE7","#FF9418","#219431","#9C52AD"))
mycolour_line_7<-scale_color_manual(values=c("#085A9C","#EF0808","#526373",
                                            "#0C8DC4","#FF9418","#219431","#9C52AD")) 

把以上代码在R里面运行以后,就可以直接使用了。譬如以下:

1)先生成一个简单的图表:

#未使用格式刷
p<-ggplot(iris,aes(x=species,y=sepal_length)) +geom_bar(stat="identity")+ ggtitle("sepal_length by species")
p

简单地指定x轴为离散型变量species,y为求和,会得到下面的柱形图 

这时候,套用一下之前设置好的主题(mytheme),背景、坐标轴还有字体颜色就相应改变了。

p+mytheme

然后,因为之前格式刷部分我设定了一个蓝色的柱形图样式(mybar),这里直接引用的话,就可以直接生成蓝色的柱形图了。

ggplot(iris,aes(x=species,y=sepal_length)) +ggtitle("sepal_length by species")+mybar+mytheme

2、画图前的准备:数据塑形利器dplyr / tidyr

有了事先设定的一些格式刷以后,我们就可以快速有效地作图了。

但是在作图之前,就像excel作图总要先把数据用处理成想要的形式 。在excel里面,我们常用的是数据透视表或者一些公式辅助,而在R里,则是用一些常用的包,如dplyr及tidyr,对数据进行重塑再造

在我之前看的那两本ggplot2的书里,基本用的都是reshape2+plyr的组合。但实际上hadley后续出的dplyr与tidyr更加有用。具体的使用方法,在JHU Getting and cleaning data有介绍,老师还编了一个swirl课程供人使用,安装方法如下。

install.packages("swirl")
library(swirl)
#安装getting and cleaning data相关的课程教学包
install_from_swirl("Getting and Cleaning Data")
swirl()

其他的也可以参考我这篇博文

总之,用好dplyr的话,你可以快速的把一些数据,如下面的股票逐笔成交记录 
 
随你所欲地汇总(group_by & summarize) 甚至再拆分 (spread),譬如示例里面就是把成交记录按照成交价格和BuySell拆分

data #刚刚演示的那些数据,在预测者网可以下载
data %>% group_by(Price,BuySell) %>% summarize(Money=sum(Money,na.rm=TRUE)) %>% spread(BuySell,Money)

要想做好ggplot2的图,对数据快速进行塑形的方法是我们必须要掌握的。上面的s wirl课程非常有用,而且值得是最新的一个技术方法,值得大家学习。

3、常用的商业用图

接下来分享一下我在这次作图过程中,最常用的几个图形的代码。首先声明,这些图形的进一步做法以及变形,基本都可以在这两本参考书籍里(R可视化技术 | ggplot2:数据分析与图表技术 )找到。我这里更多的摘取一些我比较常用的图表进行讲解

1、简单柱形图+文本(单一变量) 
2、分面柱形图(facet_wrap/facet_grid) 
3、簇型柱形图(position=”dodge”) 
4、堆积柱形图(需要先添加百分比,再对百分比的变量做柱形图) 
5、饼图、极坐标图 
6、多重线性图

在作图之前,首先讲一下ggplot2的局限。

ggplot2最大的局限是,它基本不支持双坐标图和饼图。即使能做这些图形,也要很多设置,做起来非常繁琐。 
按我个人理解,这个局限的根源与ggplot2开发者Hadley本身的审美习惯以及分析习惯脱不了关系。具体请看他在stackoverflow的这一段问答:

It’s not possible in ggplot2 because I believe plots with separate y scales (not y-scales that are transformations of each other) are fundamentally flawed.

大神有技术就能任性。即使一堆人在他那回复下面各种求双坐标。。不知道Hadley现在有没有改变主意,把双坐标列为ggplot2的下一个更新点。但是如果你想画双坐标图或者饼图,至少经个人的实践,这些都是比较困难的,设置繁琐而且不美观。要么选择用excel完成,要么听大神的话,用分面图(facet)或者柱形图代替,会更加省事一些。

所以,在了解以下常用图形前,我们需要记住,ggplot2不是万能的,它虽然能做出非常美观的图表,但是总有一些图不能做,因此多个工具结合使用是非常必要的。

在知道以上前提下,我们以ggplot2自带的diamonds数据集为基础,结合dplyr/tidyr的应用,介绍一下常用图形的画法。

然后来讲一下除了双坐标图和饼图以外,ggplot2可以支持的常用图形的画法。数据的话,我们使用ggplot2自带的数据包diamonds

首先定义一下

mytitle="演示:以diamond为例"

1)简单柱形图 

 
代码组成如下,这里使用格式刷mybar和mytheme,然后用geom_text添加柱形图标签(vjust=1表示在柱形图里面显示)

data1<-diamonds %>% group_by(cut) %>% summarize(avg_price=mean(price))
柱形图<-ggplot(data1,aes(x=cut,y=avg_price,fill=as.factor(cut)))+
       mytitle+mybar+mytheme+
       geom_text(aes(label=round(avg_price)),vjust=1,colour="white")

2)带分类的柱形图

举个例子来说,在有时候,我们想要快速绘图。使用facet_wrap或者facet_grid可以快速绘制相应图形。这也是ggplot2不太支持双坐标的原因:可以快速绘图,就不需要做那么多无用功了。 
 
代码如下:

#dplyr处理数据
data2<-diamonds %>% group_by(cut,color) %>% summarize(avg_price=mean(price))
#画图,套用设定好的绘图元素
ggplot(data2,aes(x=color,y=avg_price))+facet_wrap(~cut,ncol = 2)+
       mytitle+mybar+mytheme
#在facet_wrap里面,如果加上scales="free"的话,坐标就不一样了。

 3)簇型图 

制图要点是,对数据作图后,添加geom_bar时,position=”dodge”(分开的)如果去掉这部分,默认是生成堆积图.

代码如下:

data3<-diamonds %>% filter(cut %in% c("Fair","Very Good","Ideal")) %>%
       group_by(cut,color) %>% summarize(avg_price=mean(price))
#簇状图
簇状柱形图<-ggplot(data3,aes(x=color,y=avg_price,fill=cut))+
       geom_bar(stat="identity",position="dodge")+
       mytheme+mytitle+mycolour_3
簇状柱形图

这里如果想要定义颜色的相应顺序的话,可以使用factor 

譬如以下,只是用这行代码对颜色重新定义一下,用levels改变factor顺序,再画图的时候,颜色以及柱子顺序就会跟着改变了。非常方便。

data3$cut<-factor(data3$cut,levels=c("Very Good","Ideal","Fair"))

4)百分比堆积图 

制图前要事先添加一个百分比的数据之后才好作图,这里我们用mutate(percent=n/sum(n))添加该百分比数据。同时去掉position=”dodge” 

data4<-diamonds %>% filter(cut %in% c("Fair","Very Good","Ideal")) %>%
        count(color,cut) %>%
       mutate(percent=n/sum(n))
堆积图<-ggplot(data4,aes(x=color,y=percent,fill=cut))+mytitle+
       geom_bar(stat="identity")+mytheme+mytitle+mycolour_3
堆积图

当然,也可以做面积图。不过如果数据有缺失,面积图出错几率蛮大的

5)饼图以及极坐标图

参考一下这篇文章《【R】初吻R–ggplot绘制Pie Chart饼图》以及这篇文章使用ggplot2画图 
在ggplot2里并没有直接画饼图的方法,基本上都是先画出柱形图,再用coord_polar转化为饼图

有两种作图方法: 
1)不指定x轴,直接用geom_bar生成y轴,然后fill=分类颜色,coord_polar直接投影y 
该方法的好处代码是比较简单(coord_polar(“y”) 
加标签方法请见: http://stackoverflow.com/questions/8952077/pie-plot-getting-its-text-on-top-of-each-other# 

data5<-diamonds %>% count(cut) %>% 
       mutate(percent=n/sum(n))
ggplot(data5,aes(x=factor(1),y=percent,fill=cut))+geom_bar(stat="identity",width=3)+mycolour_7+
       coord_polar("y")+pie_theme+mytitle

2)指定x轴,x轴同时也是颜色(fill),先画柱形图,再转化为圆形。坏处是公式相对比较繁琐一些。

ggplot(data5,aes(x=cut,y=percent,fill=cut))+
       geom_bar(stat="identity",width=3)+
mycolour_7+coord_polar("x")+pie_theme+mytitle

但是我尝试了多次,在饼图里加标签方法非常难以理解。。如果要饼图加标签的话,或许还不如柱形图

附上分面柱形图画法: 

data5_1<-data5 %>% filter(color %in% c("D","E","F","G"))
ggplot(data5_1,aes(x=factor(1),y=percent,fill=cut))+geom_bar(stat="identity",width=3)+mycolour_7+
       coord_polar("y")+pie_theme+facet_wrap(~color,ncol = 4)+
       theme(legend.position="bottom")+mytitle

6、折线图

除了以上柱形图以外,折线图我们做的也比较多。 
简单的折线图直接做就好了 
然后像下图这样的 

要点是,先做成如A-B-变量这样的二联表,然后,x轴为A,group为b,colour为b 
下面代码展示了这个处理 
如果去掉group的话,折线图会不知道怎么去处理数字。

data6<-diamonds %>% count(color,cut) %>% filter(color %in% c("D","E","F"))%>%
       mutate(percent=n/sum(n))
ggplot(data6,aes(x=cut,y=n,group=color,colour=color))+geom_line(size=1.5)+mypoint+
       mycolour_line_7+mytheme+mytitle

还有一些其他有用的图形 
总之,ggplot2的语法还是比较独特的,而且其实处处有坑,处处有惊喜。如果作为商业绘图的话,需要一点一点地去探索去改变,保证风格和细节完美无缺。 
不过ggplot2绘图有个好处是,一旦整理出常用的绘图代码,以后就可以无限次套用,尤其是那些格式刷,事先设定好的主题等。即ggplot2绘图,是完全可以做到越绘越快,再开发成本低廉的。

 

另外补充说明的是,ggplot2绘图,个人更看好其多种映射,以及在探索性数据分析里快捷绘图的能力,还有跟地图啊等结合的能力。还有动态交互等等。

譬如现在比较流行的R/Python与动态网页(大部分是D3)的结合 示例1,示例2

但愿各位不要将绘图局限于上述所选的一些最常用的图形与格式化调整里。请容我吐槽一句,这样子调风格学习真的很苦(づ ̄ ~~ ̄|||)づ


End

转自:http://mp.weixin.qq.com/s?__biz=MzA3MTM3NTA5Ng==&mid=2651055257&idx=1&sn=786922515def9e46ce991178a082e881&chksm=84d9c50eb3ae4c181313a495965f4578653955ab6566899e0f4ec4b73f4d2bddebfc5e7b6288&scene=0#rd

 

转载于:https://www.cnblogs.com/payton/p/6078094.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/542221.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux中常用的命令

1.文件建立 touch file&#xff08;文件的名字&#xff09; 注意&#xff1a; touch不但可以建立文件也可以修改文件的时间戳 时间戳分为&#xff1a; atime&#xff1a;文件内容被访问的时间标识 mtime&#xff1a;文件内容被修改的时间标识 ctime&#xff1a;文件属性或文件内…

Linux系统中输出输入的管理

1.什么是输入和输出 输入和输出是计算机系统中的主机与外部进行通信的系统。它由外围设备和输入输出控制系统两部分组成&#xff0c;我们在shell中键入指令&#xff0c;然后送入CPU中运算产生结果&#xff0c;再将结果送到字符设备中显示。简单点来说输入输出就是通过我们的键盘…

Linux系统中用户的管理

#####用户管理###### 1在Linux中&#xff0c;有三种用户&#xff1a; 1 root : 也成为超级用户&#xff0c;对系统有控制权限&#xff0c;超级用户可以不受限制的运行任何命令&#xff0c;root 用户可以看作是系统的管理员。 2 系统用户&#xff1a; 系统用户通常为系统功能所必…

Linux中对进程的管理

1.what is 进程 程序&#xff08;program&#xff09;放置在储存媒体中&#xff08;如硬盘、光盘、软盘、磁盘等&#xff09;&#xff0c;为实体的型态存在。 进程&#xff1a;程序被触发后&#xff0c;执行者的权限与属性、程序的程序码与所需数据等都会被载入内存中&#xff…

Linux远程连接与sshd服务安全设定

1.远程连接&#xff1a; 首先设置ip&#xff1a; 设置好之后&#xff0c;先ping一下IP 看能不能通 ssh root172.25.13.103 ##表示的是&#xff1a;连接ip为172.25.13.103的root用户 2.系统控制命令 系统控制命令的查看相关参数如下表 systemctl服务控制命令systemctl stat…

一个简单的封ip规则

2019独角兽企业重金招聘Python工程师标准>>> 一个简单通过nginx日志封ip规则&#xff08;仅仅自己方便使用&#xff09; #!/bin/bash #Version:1.0 #Date:2016-08-09 #作用:防刷IP地址,解封蜘蛛,解封5天前封的IP地址function deny () { Date$(date "%F-%H-%M&q…

系统日志管理

1 查看系统中的日志 rsyslog 此服务是用来采集系统日志的&#xff0c;他不产生日志&#xff0c;只是起到采集作用 2 rsyslog 的管理 /var/log/messages服务信息日志/var/log/secuer系统登陆日志/var/log/cron定时任务日志/var/log/maillog邮件日志/var/log/boot.log系统启动日…

iOS10 UI教程视图的边界与视图的框架

2019独角兽企业重金招聘Python工程师标准>>> iOS10 UI教程视图的边界与视图的框架 iOS10 UI视图的边界 在视图的几何形状中我们提到了视图属性中的一部分属性可以将定义的视图绘制在屏幕上。其中典型的3个属性为边界属性、框架属性以及中心位置属性。 bounds表示的就…

Linux中远程文件的传输

1. scp命令 scp file userip:/dir 把自己主机的文件远程复制到其他主机 scp userip:/file dir 把其他主机的文件远程复制到当前主机 注意&#xff1a;要关闭接受端的防火墙 把主机的file远程复制到IP为172.25.254.117的root用户的Desktop 把IP为172.25.254.117的root用户Deskt…

引入antd组件样式_个人作品:一个技术栈koa2+ mysql+react + antd的个人博客

前言此项目是个人博客&#xff0c;有前端界面后台管理系统&#xff1b;目的是当做react和node的练手项目&#xff0c;同时还可以了解到服务器nginx部署web站点以及备案和域名的基本操作流程。项目预览地址https://www.lxsblog.cn​www.lxsblog.cnGitHub地址LinWeb/blog​github…

浅谈Jfinal急速开发框架

2019独角兽企业重金招聘Python工程师标准>>> 使用Jfinal一段时间了,记得当初14年吧,为了建立一个简单的门户网站,想找个轻量型的急速开发框架,然后搜到Jfinal,然后用了一段时间后,确实不错, 现在吧,随着时间的推移,作者对JFinal的版本迭代也是一直在努力,一直朝着优…

虚拟机的管理

我们采用虚拟机的原因是什么呢&#xff0c;很简单就俩字&#xff1a; 节能 1. 管理虚拟机的命令&#xff1a; virt-manager开启虚拟机管理器virsh list显示正在运行的虚拟机virsh list --all查看所有虚拟机virsh start desktop打开虚拟机virsh shutdown desktop正常关闭虚拟机…

Linux中的软件管理

1. 使用已有的网络安装资源安装软件 cd /etc/yum.repos.d/ (移动到yum源指向的文件配置目录下&#xff09; vim westos.repo &#xff08;新建文件&#xff0c;yum下后缀必须为.repo) 编辑这个文件里面写 [redhat] &#xff08;软件仓库名称&#xff09; namefirefox &#x…

android--------Popupwindow的使用

2019独角兽企业重金招聘Python工程师标准>>> PopupWindow在Android.widget包下&#xff0c;项目中经常会使用到PopupWindow做菜单选项&#xff0c; PopupWindow这个类用来实现一个弹出框&#xff0c;可以使用任意布局的View作为其内容&#xff0c;这个弹出框是悬浮…

安装虚拟机的脚本

1. 先安装生成自动安装脚本的工具 yum install system-config-kickstart -y 2. 打开这个软件 system-config-kickstart 基本设置&#xff1a;更改时区为上海&#xff0c;设置root用户密码 2&#xff09;设置安装方法为网络安装&#xff0c;将共享的镜像文件地址正确填写 3&…

小小小游戏

写着玩 FlappyBird 视频:https://pan.baidu.com/s/1sljIR5z 游戏:https://pan.baidu.com/s/1ge8j7Ej 项目:https://pan.baidu.com/s/1eSysxpw Breakout 视频:https://pan.baidu.com/s/1gfhv4hd 项目:https://pan.baidu.com/s/1hs8xPly QBert 视频:https://pan.baidu.com/s/1s…

系统延时任务及定时任务

1. 系统延时任务&#xff1a; at相关命令 at time 设定任务执行时间at> rm -fr /mnt/* 任务动作at> <EOT> <<ctrld 执行任务at的命令&#xff1a; -l ##查看任务列表-c …

cpn tools查看运行时间_Jmeter在Linux下的运行测试

一、JMeterApache JMeter是Apache组织开发的基于Java的压力测试工具。用于对软件做压力测试&#xff0c;它最初被设计用于Web应用测试&#xff0c;但后来扩展到其他测试领域。1.1、JMeter的作用能够对HTTP和FTP服务器进行压力和性能测试&#xff0c; 也可以对任何数据库进行同样…

css div滚动_如何使用CSS创建可垂直滚动的div?

css div滚动Introduction: 介绍&#xff1a; Dealing with divs has become a regularity and divs are used for many purposes like to structure our code and to segregate our various sections of codes. Besides, we are also aware of many properties that we can im…

Linux中磁盘分区的管理

1. 本地存储设备的识别 fdisk -l真实存在的设备cat /proc/partitions系统识别的设备blkid系统可使用的设备df系统正在挂载的设备 真实存在的设备不一定可识别&#xff0c;识别到的的设备不一定可使用 2. 设备的挂载和卸载 1&#xff09;设备名称 /dev/xdx …