Python可视化库——plotnine学习和使用
plotnine简介
plotnine学习背景
作为一名python的初学者,做数据分析的时候学的也都是python自带的matplotlib和seaborn,后来公司的一个学习R语言的同事拿R语言的ggplot2作图,做的又快又好,他给我推荐了python的plotnine库,使用方式与R语言很相似,做出来的图也很好看,我试了一下,果真如此。然后趁有时间就整理一下plotnine的绘图,如果有什么不严谨或者不对的地方请大家指出来,谢谢。如果有更多想学的可以点击:plotnine官网
plotnine的优点
- 代码简洁,易学习看懂
- 绘制的图流畅大方,不需要很多的代码就可以绘制很不错的图
plotnine的使用
plotnine安装导入
我们可以用pip直接安装
pip install plotnine
导入plotnine库
from plotnine import *
基本和常用语法(目前我用到过的)
基本语法
创建一个图形对象
基本语法 | Value |
---|---|
ggplot | 创建对象 |
aes | 数据中的变量到图形成分的映射 |
几何对象geom
几何对象geom负责每个数据点的可视化,geom_后面的部分决定几何对象的类型,每个图至少添加一个几何对象,不同的视觉对象由aes控制映射
基本语法 | Value |
---|---|
geom_area | 面积图 |
geom_bar | 条形图(饼图) |
geom_blank | 空的几何对象,什么也不画 |
geom_histogram | 直方图 |
geom_line | 线图 |
geom_point | 点图 |
geom_map | 地图 |
geom_boxplot | 箱线图 |
geom_violin | 小提琴图 |
统计变化stat
统计变换再数据被提取出来之前对数据进行聚合和其他计算,用stat_确定对数据进行的计算类型,不同类型的计算统计产生不同的图形结果
基本语法 | Value |
---|---|
stat_abline | 添加线条,用斜率和截距表示 |
stat_bin | 分割数据,然后绘制直方图 |
stat_identity | 绘制原始数据,不进行统计变化 |
标度函数scale
标度函数scale是对数据图形的调整,通过scale_这样的函数将获取的数据进行调整以改变图形的长度、颜色、大小和形状。
基本语法 | Value |
---|---|
scale_x_date | x轴标签是日期 |
scale_x_datetime | x轴标签是时间 |
scale_y_date | y轴标签是日期 |
scale_y_datetime | y轴标签是时间 |
xlim | x轴范围 |
ylim | y轴范围 |
标签Labels
这个就不用解释了吧
基本语法 | Value |
---|---|
labs | 设置所有的标签和标题 |
xlab | 设置x轴标签 |
ylab | 设置y轴标签 |
ggtitle | 创建图表标题 |
完整公式
- 一个括号
( - 基本公式:用ggplot创建图形,geom_创建几何对象
ggplot(df,aes())+geom_()) - 调整公式
+scale+theme······ - 最后一个括号
)
例如:
绘制图像(最基本的图像)
条形图
我们先对比一下
plotnine绘图
matplotlib绘图
这样就可以看出plotnine绘图确实比matplotlib绘图要好看多了,而且简洁大气
我们先先导入我们需要的库
from plotnine import *
import pandas as pd
我们导入数据,我这边是已经处理过了的数据,为方便大家理解,我先把原始数据转为字典,然后直接转为DataFrame
median_age_dict={
'Country': ['New Zealand','Spain','Ireland','Israel','Denmark','Norway','Netherlands','Australia','Italy','Sweden'],
'Age': [39.0, 37.0, 35.0, 34.0, 34.0, 34.0, 34.0, 34.0, 34.0, 34.0]
}
median_age=pd.DataFrame(median_age_dict)
我们看一下数据
然后我们开始绘图
(
ggplot(median_age,aes(x='Country',y='Age'))#创建图象,传入数据来源和映射
+ geom_bar()#建立几何对象,画直方图
)
这时候会报错,因为直方图需要设置数据统计方式,需要用stat这个参数在geom_bar里面传入统计方式,统计方式为identity,即用数据表原有的数据进行统计
(
ggplot(median_age,aes(x='Country',y='Age'))#创建图象,传入数据来源和映射
+ geom_bar(stat='identity')#建立几何对象,画直方图
)
我们可以看到这时候已经绘制出一幅纵向直方图,我们想要得到我们需要的图,我们要进行以下的处理
- 不同国家画不同的颜色
- 每一个国家添加数据标签
- 将纵向直方图转置变为横向直方图
- x轴没有按照顺序排序,需要让它按照数据顺序排序
- 每一个条形图的粗细需要调整
- **添加图表标题 **
我们一个一个来
将不同国家填充不同的颜色在映射里面添加fill参数可以将数据以颜色区分
(
ggplot(median_age,aes(x='Country',y='Age',fill='Country'))#创建图象,传入数据来源和映射
+ geom_bar(stat='identity')#建立几何对象,画直方图
)
这样我们就将不同的国家都填充上了不同的颜色
然后我们给他添加数据标签,添加数据标签需要用geom_text文本来绘图,同样需要添加映射
(
ggplot(median_age,aes(x='Country',y='Age',fill='Country'))#创建图象,传入数据来源和映射
+ geom_bar(stat='identity')#建立几何对象,画直方图
+ geom_text(aes(x='Country',y='Age',label='Age'))#添加数据标签
)
但是这个数据标签的位置不太好,我们要让它往上移一下,利用nudge_y参数
(
ggplot(median_age,aes(x='Country',y='Age',fill='Country'))#创建图象,传入数据来源和映射
+ geom_bar(stat='identity')#建立几何对象,画直方图
+ geom_text(aes(x='Country',y='Age',label='Age'),nudge_y=2)#添加数据标签
)
这样数据标签就添加好了
我们可以将他转为横向的直方图,这时候我们利用coord_flip函数
(
ggplot(median_age,aes(x='Country',y='Age',fill='Country'))#创建图象,传入数据来源和映射
+ geom_bar(stat='identity')#建立几何对象,画直方图
+ geom_text(aes(x='Country',y='Age',label='Age'),nudge_y=2)#添加数据标签
+ coord_flip()#纵向直方图转换为横向直方图
)
我们发现这个图并没有按照我们的数据表格从大到小绘制,这是因为plotnine是默认按照x轴文本的字母顺序降序,这一点跟R语言的ggplot2库是同样的,但是ggplot2可以用reorder函数进行排序,python里面不能用这样的函数,我试了好久,最后找了一个方法,用xlimx轴标签范围的函数来排序
(
ggplot(median_age,aes(x='Country',y='Age',fill='Country'))#创建图象,传入数据来源和映射
+ geom_bar(stat='identity')#建立几何对象,画直方图
+ geom_text(aes(x='Country',y='Age',label='Age'),nudge_y=2)#添加数据标签
+ coord_flip()#纵向直方图转换为横向直方图
+ xlim(median_age['Country'])#x轴排序
)
这是按年龄升序的,我们将xlim里面的列表降序排列
(
ggplot(median_age,aes(x='Country',y='Age',fill='Country'))#创建图象,传入数据来源和映射
+ geom_bar(stat='identity')#建立几何对象,画直方图
+ geom_text(aes(x='Country',y='Age',label='Age'),nudge_y=2)#添加数据标签
+ coord_flip()#纵向直方图转换为横向直方图
+ xlim(median_age['Country'][::-1])#x轴排序
)
好,现在顺序也对了
我们将条形图的粗细设置一下,在geom_bar里面添加width参数设置图形的粗细
(
ggplot(median_age,aes(x='Country',y='Age',fill='Country'))#创建图象,传入数据来源和映射
+ geom_bar(stat='identity',width=0.5)#建立几何对象,画直方图,设置统计方式和粗细
+ geom_text(aes(x='Country',y='Age',label='Age'),nudge_y=2)#添加数据标签
+ coord_flip()#纵向直方图转换为横向直方图
+ xlim(median_age['Country'][::-1])#x轴排序
)
这样一幅图就出来了,但是右边的图例很多余,我们要把图例隐藏,利用theme工具包里图例位置的参数legend_position
(
ggplot(median_age,aes(x='Country',y='Age',fill='Country'))#创建图象,传入数据来源和映射
+ geom_bar(stat='identity',width=0.5)#建立几何对象,画直方图
+ geom_text(aes(x='Country',y='Age',label='Age'),nudge_y=2)#添加数据标签
+ coord_flip()#纵向直方图转换为横向直方图
+ xlim(median_age['Country'][::-1])#x轴排序
+ theme(legend_position = 'none')#隐藏图例
)
最后我们给图表添上标题,利用ggtitle
(
ggplot(median_age,aes(x='Country',y='Age',fill='Country'))#创建图象,传入数据来源和映射
+ geom_bar(stat='identity',width=0.5)#建立几何对象,画直方图
+ geom_text(aes(x='Country',y='Age',label='Age'),nudge_y=2)#添加数据标签
+ coord_flip()#纵向直方图转换为横向直方图
+ xlim(median_age['Country'][::-1])#x轴排序
+ theme(legend_position = 'none')#隐藏图例
+ ggtitle('Top 10 Median age of respondents from different countries')#加上标题
)
这样我们就得到了想要的条形图。
折线图
输出目标
我们导入数据,我们这次用的数据是plotnine自带的数据集economics,这是一个某个国家在1967年到2015年每个月的经济情况的表,为了方便查看我们选取超过2013年2月的psavert数据画折线图
from plotnine.data import economics
save_rate = economics[economics['date']>'2013-01-01']
save_rate=save_rate.reset_index(drop=True)
部分数据
我们先还是用基本公式绘制折线图,将几何对象换为geom_line
(
ggplot(save_rate)#传入数据集
+ geom_line(aes(x='date',y='psavert'))#传入映射和几何对象
)
我们看到这幅图有一些问题,我们主要做下面的一些处理
- y轴的范围需要调整,因为plotnine绘图y轴会自动按y值的上下限设置范围
- x轴标签要设置成yyyy-mm格式,间隔要设置成5个月
我们先设置y轴的范围,用ylim
(
ggplot(save_rate)#传入数据集
+ geom_line(aes(x='date',y='psavert'))#传入映射和几何对象
+ ylim(0,6)#y轴的范围
)
这样我们的y轴的范围就设置好了
接下来我们设置x轴的显示文本和x轴的间隔,这时候我们就要使用到scale_x_date
我们之所以选择scale_x_date是因为我们的x轴的数据格式是datetime,如果是数字或者文本就需要用到其他的标签函数
(
ggplot(save_rate)#传入数据集
+ geom_line(aes(x='date',y='psavert'))#传入映射和几何对象
+ ylim(0,6)#y轴的范围
+ scale_x_date(breaks='5 months',date_labels='%Y-%m')#设置x轴的标签
)
用breaks设置日期间隔,可以用“5 days",“3 months”,“6 weeks”,"10 years"这样的格式设置,然后用date_labels设置x轴的文本显示格式为”%Y-%m“,这样我们就绘制出了我们要的折线图
点图
输出目标
我们还是用plotnine自带的数据集economics
from plotnine.data import economics
点图和线图的绘制方式几乎一模一样,我们只要像上面一样,只需要将几何对象换成geom_point
(
ggplot(economics)#数据来源
+ geom_point(aes('date', 'psavert'))#几何对象映射
)
我们只需要设置一下x轴文本为”yyyy"格式,间隔为10年
同样是利用scale_x_date
(
ggplot(economics)#数据来源
+ geom_point(aes('date', 'psavert'))#几何对象映射
+ scale_x_date(breaks='10 years',date_labels='%Y')#设置x轴文本和间隔
)
这样我们就获得了我们需要的点图
箱线图
输出目标
由于箱线图的数据量需要大一点,就用下面链接里的数据——文件名为“HR_comma_sep.csv”
链接:https://pan.baidu.com/s/1mkc4LzJITG-R5Q5l_Wy_1A
提取码:lvsz
我们先导入数据,我们选择数据表里的“left",“satisfaction_level”
df = pd.read_csv('HR_comma_sep.csv')[['left','satisfaction_level']]
df.left=df.left.apply(lambda x:str(x))#对数据进行一下处理
我们这里对数据进行了一下处理,为什么这样处理我们最后说。
我们开始绘制图形,这次传入的几何对象是geom_boxplot
(
ggplot(df,aes(x='left',y='satisfaction_level'))
+ geom_boxplot()#几何对象
)
我们可以看出来已经有这个模子了,但是还有一些问题,我们需要做以下调整
- 以颜色区分每个图
- 设置图的粗细
我们还是像之前一样,在映射里添加fill参数做分组
(
ggplot(df,aes(x='left',y='satisfaction_level'))
+ geom_boxplot(aes(fill='left'))#几何对象添加颜色分组
)
这样颜色就区分开了
我们在添加粗细,在geom_boxplot添加width参数,和直方图一样
(
ggplot(df,aes(x='left',y='satisfaction_level'))
+ geom_boxplot(aes(fill='left'),width=0.5)#几何对象添加颜色分组和粗细
)
OK,这样我们就得到了我们想要的箱线图
我们解释一下为什么之前要对数据处理一下
因为如果不处理的话,"left"作为x轴的数据是整型的,就没有办法作出区分,只会画出一个箱线图就是下面这种
因为R语言本身好像没有这个问题,网上其他关于plotnine的分享也没有涉及到这个问题,我试了好久,最后确定是数据类型的原因,所以大家一定要注意一下这个问题。
小提琴图
小提琴图的绘制和箱线图的绘制几乎一模一样,是真的一模一样,除了几何对象不同,小提琴图的几何对象是geom_violin
我们就不说目标,直接上代码
(
ggplot(df,aes(x='left',y='satisfaction_level'))#数据来源和映射
+ geom_violin(aes(fill='left'),width=0.5)#分组和粗细
)
绘制图像(稍微复杂一点)
堆积条形图
堆积条形图在plotnine里面绘制特别简单,跟matplotlib那么繁琐的语句而且绘制出来的很丑简直是鲜明的对比
我们的目标
我们首先导入数据,同样是我处理过之后的数据,我转换成字典,再转换成DataFrame方便练习和理解
importance_dict={
'tool': ['Python','Python','Python','R','R','R','BigData','BigData','BigData','SQL','SQL','SQL'],
'importance': ['Necessary','Nice to have','Unnecessary','Nice to have','Necessary','Unnecessary','Nice to have','Necessary','Unnecessary','Nice to have','Necessary','Unnecessary'],
'mix': [0.6459935499875962,0.32721409079632846,0.026792359216075416,0.5139452332657201,0.4148073022312373,0.07124746450304259,0.5740647118301314,0.3799292214357937,0.04600606673407482,0.49177800616649536,0.434224049331963,0.07399794450154162]
}
Jobskillimpotance=pd.DataFrame(importance_dict)
画堆积条形图同样是用geom_bar
(
ggplot(Jobskillimpotance,aes(x='tool',y='mix'))#传入数据来源和映射
+ geom_bar(stat='identity')#统计方式为原数据
)
我们可以看到条形图绘制出来,但是我们没有办法区分是哪种语言各种重要程度占比是多少,我们要用颜色将它区分出来,我们同样用fill
(
ggplot(Jobskillimpotance,aes(x='tool',y='mix',fill='importance'))#传入数据来源和映射,用颜色区分各种重要程度
+ geom_bar(stat='identity')#统计方式为原数据
)
这样就一句代码我们直接就画出来一幅不错的堆积条形图
分组折线图,并添加数据标记
然后我们现在绘制分组折线图,Excel里面还可以添加数据标记,其实plotnine也可以,而且很简单,但是matplotlib就不行,至少我没有找到过,我们来看plotnine怎么会之分组折线图并添加数据标记
输出目标
我们可以看到上面这张图共两条线,每条线的颜色也不一样,而且每条线上还有数据标记更容易区分,其实就是折线图和点图在同一块画布上作图,这样就可以得到带数据标记的折线图了。
我们先导入数据,还是用之前百度网盘里面的另外一个文件,文件名为"trans.xlsx"
#导入数据
df=pd.read_excel('trans.xlsx')
我们先用geom_line绘制折线图
(
ggplot(df,aes(x='year',y='mix'))#数据源和映射
+ geom_line()几何对象
)
这样看我们主要做一下调整:
- 将折线图分组
- 设置y轴范围
- 添加数据标记
- 将x轴的文本设置为"yyyy"格式
我们先将折线图分组,我们像之前一样用fill参数分组
(
ggplot(df,aes(x='year',y='mix',fill='gender'))
+ geom_line()
)
我么看到折线图已经按gender分组了,但是并没有像之前的一样用颜色做了改变,这时候我们要在映射里面添加一个参数color,写法和fill一样
(
ggplot(df,aes(x='year',y='mix',fill='gender',color='gender'))
+ geom_line()
)
这时候我们可以看出折线图以颜色分开了,我们设置y轴的范围和线条的粗细,y轴的范围用ylim,线条的粗细在geom_line里面添加size参数设置
(
ggplot(df,aes(x='year',y='mix',fill='gender',color='gender'))
+ geom_line(size=1)#折线图线条粗细
+ ylim(0,6)#y轴的范围
)
接下来我们给图上添加数据标记,用绘制点图的方式,即用geom_point来绘制
(
ggplot(df,aes(x='year',y='mix',fill='gender',color='gender'))
+ geom_line(size=1)
+ geom_point()#添加数据标记
+ ylim(0,6)#y轴范围
)
虽然添加了数据标记,但是数据标记都是圆点,这能有什么用,我们要对数据标记变得不同,就要在geom_point里面的映射添加一个参数shape,用法和fill一样
(
ggplot(df,aes(x='year',y='mix',fill='gender',color='gender'))
+ geom_line(size=1)
+ geom_point(aes(shape='gender'))#添加数据标记
+ ylim(0,6)#y轴范围
)
虽然数据标记不同,但是太小了,我们要让数据标记大一点,就是在geom_point里面添加size参数
(
ggplot(df,aes(x='year',y='mix',fill='gender',color='gender'))
+ geom_line(size=1)
+ geom_point(aes(shape='gender'),size=3)#添加数据标记
+ ylim(0,6)#y轴范围
)
OK,最后我们将x轴的文本设置一下,使用scale_x_date函数
(
ggplot(df,aes(x='year',y='mix',fill='gender',color='gender'))
+ geom_line(size=1)
+ geom_point(aes(shape='gender'),size=3)#添加数据标记
+ scale_x_date(breaks='5 years',date_labels='%Y')#设置x轴的间隔和表示格式
+ ylim(0,6)#y轴范围
)
这样我们就得到了我们想要的图
未完待续
Author
: 我真不是小样