在用python做数据分析后进行数据可视化时,大多都会使用matplotlib和seaborn,但这两个python自带库作图相对于R作图来说,稍有逊色,尤其对于使用过R语言的ggplot2,更是觉得无法习惯和使用。但是好东西从来不乏分享,正所谓酒香不怕巷子深,于是适合python平台的一个新的库plotnine被人开发和挖掘出来了,它的语法风格秉持了ggplot2的风格,甚至参数都一样。其代码简洁易学易懂、图形大方流畅是其最大的特点。
其官网为:https://plotnine.readthedocs.io。
先来看看matplotlib作图情况。
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签
plt.rcParams['axes.unicode_minus']=False #用来正常显示负号
x = np.arange(-10,11)
y = x**2
z = x+50
## 定义一个图像窗口大小
plt.figure(figsize=(8,5))
## 按x、y坐标绘制图形
plt.plot(x,y)
plt.plot(x,z)
## 加标识、标题
plt.title("para-curve实例") # 抛物线与直线的割
plt.xlabel("x轴")
plt.ylabel("y轴")
#x轴刻度 【plt.xticks(x,label,rotation=40, color="r",size=10)】
plt.xticks(x,x,rotation=40, color="r",size=10) #将x轴上标度倾斜40°,红色,字体大小为25。
plt.axis("equal")
plt.show()
##保存图像
#plt.savefig('./test2.jpg') #将图片保存在当前的环境目录下
再看plotnine作图。
from plotnine import *
import pandas as pd
%matplotlib inline
x = np.arange(-10,11)
y = x**2
z = x+50
data = pd.DataFrame({"x":x,"y":y,"z":z})
(ggplot(data, aes(x=x,y=y))
+ geom_line(stat='identity',color="blue")
+ geom_line(aes(x=x,y=z),size=1,color="red")
+xlab('x轴') #重命名x轴名称
+ylab('y轴') #重命名y轴名称
+ggtitle('抛物与直线')
+theme_matplotlib()
+theme(text=element_text(family='SimHei'))
)
<ggplot: (150994535409)>
跟其他第三方库安装一样,可直接使用pip install plotnine。
使用时需导入该库:from plotnine import *
此处用的0.10.1版本,查看版本如下。
import plotnine as pn
print(pn.__version__)
0.10.1
使用的基本框架模式如下,各种功能用“+”连接叠加,最后用一个完整的括号()首位包裹起来。 ( ggplot(df,aes()) + geom_xx())+ scale_xx() + theme() + …)上面的绘图模式框架就像的公式一样,其中: ggplot用于创建图形, df为数据框, aes为数据中的变量到图形成分映射,即指定x,y; geom_xx()为创建几何对象,如饼图geom_bar,线图geom_line; scale_xx()、theme()为调整坐标轴上的元素,如颜色深浅,大小范围以及图像的图例等。 对于多个图形的叠加,直接在括号内继续用“+”链接即可。 aes()可以放在ggplot()里也可以具体写在geom_xx()里,区别是ggplot()对象里的aes具有全局优先级,在画多个图时体现。 通过上面的基本框架可做如下归纳,分为必须有的函数和可选函数。
必选:(ggplot(data,aes) + geom_xxx()|stat_xxx()) 可选:(scale_xxx() + coord_xxx() + facet_xxx() + guides() + theme()) 选好数据,aes决定映射对象,geom决定映射方式,scale决定映射细节,coord决定坐标轴选择(反转和转换等),facet决定分面,guides决定图例,theme决定整体主题。 先看个简单的例子,数据如下。 date name price totle 0 2023/1/26 a 39.0 2.0 1 2023/2/23 c 34.0 3.0 2 2023/3/22 b 36.0 5.0 3 2023/4/20 d 31.0 4.0 下面开始对name列和price两列做条形图。
#导入库
from plotnine import *
import pandas as pd
#创建/导入数据
m={'date':["2023/1/26","2023/2/23","2023/3/22","2023/4/20","2023/5/20","2023/6/20"],
'name': ['a','c','b','d','m','n'],
'price': [39.0, 34.0, 36.0, 31.0,33.0,38.0],
'totle': [2.0, 3.5, 5.0, 4.0,3 ,6]}
data = pd.DataFrame(m)
data
date | name | price | totle | |
---|---|---|---|---|
0 | 2023/1/26 | a | 39.0 | 2.0 |
1 | 2023/2/23 | c | 34.0 | 3.5 |
2 | 2023/3/22 | b | 36.0 | 5.0 |
3 | 2023/4/20 | d | 31.0 | 4.0 |
4 | 2023/5/20 | m | 33.0 | 3.0 |
5 | 2023/6/20 | n | 38.0 | 6.0 |
#开始画图
(ggplot(data, aes(x='name',y='price')) + geom_bar(stat='identity'))
# stat=identity表示用数据表原有的数据进行统计,见图1。也可用geom_col()函数画柱状图,不需stat参数
<ggplot: (150994695304)>
p =(ggplot(data, aes(x='name',y='price',fill='name'))+geom_bar(stat='identity')) #见图2
print(p)
p + coord_flip() #这种写法更简洁,加了coord_flip()函数实现了旋转轴,见图3
<ggplot: (150994647188)>
从图1到图3实现用了很简短几个函数和参数,即实现了从单一条形图到分颜色的条形图,再到条形图的旋转。
说明:
1)映射aes有参数x、y,还有参数 fill 和 color 用来分组和着色,其值可按照指定的列赋值。对于条形图x轴默认按照文本的字母顺序排序。
2)geom_bar的stat参数表示本图层数据使用的统计变换(statistical transformation),geom_bar默认的是stat=count。表示的是y值是x变量的计数,因此aes(x='x',y='y')的情况下需要设置stat="identity"。在plotnine中,geom_col()更像传统意义的柱状图绘制方法
#比较pandas.plot作图
data[["name","price"]].plot()
<Axes: >
data[["name","price"]].plot.bar()
<Axes: >
上面已经使用函数geom_bar()简单的实现了条形图的画法,并在映射aes里面添加参数fill对条形块填充不同的颜色,还使用函数coord_flip()对轴进行旋转。但是图形上还缺少很多元素,如每个条形块上的数据标签、条形的宽度粗细和轴上的数据排序等。
1)添加数据标签
对每个条形块上进行数据标注,可使用geom_text()函数来实现,需要给函数参数aes,其中label表示要标注的数据来源。比如在每个条形块的上方标注数据。续接上面的代码。
p + geom_text(aes(x='name',y='price',label='price')) #添加数据标签,见图4
<ggplot: (150994661307)>
但是上面的图形数字标注的位置不是很理想,需要将数字往上在挪一点,在geom_text()中添加nudge参数即可。
p+geom_text(aes(x='name',y='price',label='price'),nudge_y=2)#向上挪移数据,见图5
<ggplot: (150861977046)>
2)隐藏图例
图中的图例有点多余,我们可以将其隐藏。叠加theme()函数,参数为legend_position=’none’即可。
p + geom_text(aes(x='name',y='price',label='price'),nudge_y=2) \
+ theme(legend_position = 'none') #隐藏图例,见图6
<ggplot: (150862060051)>
3)设置条形块的宽度
在geom_bar()函数中添加宽度参数width参数。
q = (ggplot(data,aes(x='name',y='price',fill='name')) +
geom_bar(stat='identity',width=0.5) + #宽度
geom_text(aes(x='name',y='price',label='price'),nudge_y=2) +
theme(legend_position = 'none')) #见图7
print(q)
4)添加标题
在图中添加标题,需叠加ggtitle()函数。
q + ggtitle("here is title") #添加标题,见图8
<ggplot: (150994535449)>
但若标题中添加的是中文标题,则会显示乱码,由于plotnine默认的字体是没有中文字体,所以需要我们指定显示的中文字体。则需要在theme()函数中增加关于字体设置的参数text=element_text(family='SimHei'),这里的'SimHei'是黑体。
w = (ggplot(data,aes(x='name',y='price',fill='name')) +
geom_bar(stat='identity',width=0.5) +
geom_text(aes(x='name',y='price',label='price'),nudge_y=2) +
theme(legend_position = 'none',text=element_text(family='SimHei')) + #显示中文
ggtitle("这里是标题") #见图8
)
print(w)
5)坐标轴设置
在作图时,plotnine的y轴会自动按y值的上下限默认设置范围,所以有时候为了图形的需要,需对轴的范围进行调整,另外如x轴标签要设置成yyyy-mm格式,或者间隔设置成5个月,这就需要对轴进行重新设置。 先看看对y轴的显示范围进行设置,用ylim()函数。同样,当x轴为数值时,也可以用xlim()对x轴显示范围进行设置。
w + ylim(0,50) #y轴的范围,见图10
<ggplot: (150994534720)>
当x轴需要显示日期格式时,就要使用到scale_x_date,我们之所以选择scale_x_date是因为x轴的数据格式是datetime,如果是数字或者文本就需要用到其他的标签函数。使用scale_x_date进行设置时,其参数date_labels='%Y-%m'设置显示格式,参数breaks='5 months'表示显示间隔。这里我们对data的date和price两列数据做折线图,折线图用geom_line()函数显示。
(ggplot(data)+ geom_line(aes(x='date',y='price',group = 1))) #见图11
<ggplot: (150862218466)>
由于x轴不是数值型,所以需要加上group参数避免报错。geom_line绘制折线图,默认的x轴需要是数值型变量,分类变量需要设置group参数,group = 1。 上面的date是日期格式,但并不是日期数据类型。我们也可以将date列数据处理成日期数据类型。
import datetime
import pandas as pd
data["date"] = [pd.to_datetime(i) for i in data.date]
在可直接对数据进行绘图,如图12。
e = (ggplot(data,aes(x='date',y='price')) + geom_line())
e
<ggplot: (150862253818)>
图12中的x轴比较拥挤,可以对x轴标签用theme()函数的axis_text_x参数设置进行旋转一个角度以错开显示。
e + theme(axis_text_x = element_text(rotation=60,size=10)) #旋转x轴标签,见图13
<ggplot: (150862253761)>
对于日期格式,用breaks设置日期间隔,可以用“5 days",“3 months”,“6 weeks”,"10 years"这样的格式设置,然后用date_labels设置x轴的文本显示格式为”%Y-%m“,这样我们就绘制出了我们要的折线图。
e + scale_x_date(breaks='2 months', date_labels='%Y-%m') #见图14
<ggplot: (150862386929)>
注意breaks的参数值2和months之间有一个空格。
散点图和折线图基本相同,只是绘图函数变为geom_point。绘图类型取决于geom_后面的部分,常见绘图类型如下表1所示。
表1 绘图类型函数
基本语法 描 述 geom_blank 什么也不画 geom_bar 条形图(饼图) geom_line 线图 geom_point 点图 geom_area 面积图 geom_histogram 直方图 geom_map 地图 geom_boxplot 箱线图 geom_violin 小提琴图 geom_text 设置标签文本,需要添加映射说明:geom_xx()常会用到的参数,geom_xx(alpha=0.5,colour='black',size=0.25)。其中alpha表示图像的透明度,color表示图形轮廓用的显示颜色,size表示图形的大小粗细。
6) 主题theme_xx
主要用来修改绘图的背景主题。常见主题见表5。
表5 theme_ 基本语法 描述 theme_bw 黑色网格线白色背景的主题 theme_classic 经典主题,带有x轴和y轴,没有网格线 theme_dark 黑暗背景的主题 theme_gray 灰色背景白色网格线的主题 theme_linedraw 白色背景上只有各种宽度的黑色线条的主题 theme_light 与theme_linedraw相似但具有浅灰色线条和轴的主题 theme_matplotlib 默认的matplotlib外观,白色无网格背景 theme_minimal 没有背景注释的简约主题 theme_seaborn seaborn主题 theme_void 具有经典外观的主题,带有x轴和y轴,没有网格线 theme_xkcd xkcd主题使用方法:在plotnine绘图语句中添加主题参数(后带括号),一般在绘图的格式结束之后添加。
e + theme_matplotlib() #见图15
<ggplot: (150862416044)>
7)工具库theme
定义绘图的各个方面,用于创建主题和修改现有主题。常见用法见表6。
表6 theme工具库 基本语法 Value axis_line 坐标轴的线条 axis_line_x x轴的线条 axis_line_y y轴的线条 axis_text 坐标轴的文本 axis_text_x x轴的文本 axis_text_y y轴的文本 axis_ticks 刻度线 axis_title 标题 axis_title_x x轴的标题 axis_title_y y轴的标题 dpi 像素点数 figure_size 当前绘图的画布大小 legend_backgroud 图例的背景 legend_box 图例封装 legend_box_backgroud 图例整体的背景 legend_position 图例位置 legend_title 图例标题 text 当前图象的所有文本 title 当前图像的所有标题 aspect_ratio 即高/宽,如aspect_ratio=1.5,优先使用方法:在绘图格式的最后面添加theme函数,在里面添加不同的参数调整图像,theme调整参数要按顺序来。
在theme()中设置legend.position参数¶
theme(legend_position='right') # 可以right,left,bottom,top,none(无图例)
也可以用(0.9,0.7)这种具体数值指定,一般在0-1内¶
如果使用数值设置,最好先将legend背景设为透明¶
theme(legend_background=element_rect(fill='white'),legend_position=(0.3,0.5))
8)其他设置
标度函数scale_xx()是对图形的调整,通过scale_xx()这样的函数将获取的数据进行调整,以改变图形的长度、颜色、大小和形状。scale_xx()函数类型如下表2。表2 标度函数scale 基本语法 Value scale_x_date x轴标签是日期 scale_x_datetime x轴标签是时间 scale_y_date y轴标签是日期 scale_y_datetime y轴标签是时间 xlim x轴范围 ylim y轴范围
stat统计变换在数据被提取出来之前对数据进行聚合和其他计算,用stat_xx确定对数据进行的计算类型,不同类型的计算统计产生不同的图形结果。具体见表3。 表3 统计变化stat 基本语法 描述 stat_abline 添加线条,用斜率和截距表示 stat_bin 分割数据,然后绘制直方图 stat_identity 绘制原始数据,不进行统计变化 Stat_smooth 拟合数据。参数method默认值为'auto' label主题设定,调整图表的细节,包括图表背景颜色、网格线的间隔和颜色、中文设置、图例显示、坐标轴标签字体及角度等。注意,如果图形中有中文字符,需要加入如下语句,否则将无法显示中文。 表4 标签Labels 基本语法 Value ggtitle 创建图表标题 xlab 设置x轴标签 ylab 设置y轴标签 labs 设置所有的标签和标题
对于坐标轴显示也可以用如下的方式。
import numpy as np
e = (ggplot(data,aes(x='totle',y='price'))+geom_line(colour='red',size=2))
e + scale_x_continuous(limits = (0, 6),breaks = np.arange(0,6.5,0.5)) + \
theme(figure_size=(10,5)) #见图15
#按照给定的范围以及间隔,显示完整坐标刻度。
<ggplot: (150863514347)>
堆积条形图主要是区分在该类中有哪几种构成,各构成占比是多少,并用颜色将它区分出来,这里主要使用fill分类。
data["class"]=["A","B","B","A","A","A"]
data["place"]=["an","hk","an","hk","an","hk"]
p = (ggplot(data,aes(x='class',y='totle',fill="place"))+ geom_bar(stat="identity"))
p #见图16
<ggplot: (150863648247)>
折线分组利用fill。
t = (ggplot(data,aes(x='totle',y='price',fill="place",color="place"))+ geom_line(size=1))
t + geom_point(aes(shape='place')) #设置不同的标记,见图17
<ggplot: (150863680841)>
stat_smooth拟合数据。参数method默认值为'auto',可用的方法有: 'auto' #if(n<1000)则使用loess,否则使用glm 'lm','ols' #线性模型 'wls' #加权线性模型 'rlm' #鲁棒线性模型 'glm' #广义线性模型 'gls' #广义最小二乘 'lowess' #局部加权回归(简单) 'loess' #局部加权回归 'mavg' #移动平均值 'gpr' #高斯过程回归器
e + scale_x_continuous(limits = (0, 6),breaks = np.arange(0,6.5,0.5)) + stat_smooth(method='lm')
<ggplot: (150994645544)>
from plotnine.data import mtcars
(ggplot(mtcars, aes('wt', 'mpg', color='factor(gear)'))
+ geom_point()
+ stat_smooth(method='lm')
+ facet_wrap('~gear'))
<ggplot: (150863983613)>
mtcars
name | mpg | cyl | disp | hp | drat | wt | qsec | vs | am | gear | carb | |
---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | Mazda RX4 | 21.0 | 6 | 160.0 | 110 | 3.90 | 2.620 | 16.46 | 0 | 1 | 4 | 4 |
1 | Mazda RX4 Wag | 21.0 | 6 | 160.0 | 110 | 3.90 | 2.875 | 17.02 | 0 | 1 | 4 | 4 |
2 | Datsun 710 | 22.8 | 4 | 108.0 | 93 | 3.85 | 2.320 | 18.61 | 1 | 1 | 4 | 1 |
3 | Hornet 4 Drive | 21.4 | 6 | 258.0 | 110 | 3.08 | 3.215 | 19.44 | 1 | 0 | 3 | 1 |
4 | Hornet Sportabout | 18.7 | 8 | 360.0 | 175 | 3.15 | 3.440 | 17.02 | 0 | 0 | 3 | 2 |
5 | Valiant | 18.1 | 6 | 225.0 | 105 | 2.76 | 3.460 | 20.22 | 1 | 0 | 3 | 1 |
6 | Duster 360 | 14.3 | 8 | 360.0 | 245 | 3.21 | 3.570 | 15.84 | 0 | 0 | 3 | 4 |
7 | Merc 240D | 24.4 | 4 | 146.7 | 62 | 3.69 | 3.190 | 20.00 | 1 | 0 | 4 | 2 |
8 | Merc 230 | 22.8 | 4 | 140.8 | 95 | 3.92 | 3.150 | 22.90 | 1 | 0 | 4 | 2 |
9 | Merc 280 | 19.2 | 6 | 167.6 | 123 | 3.92 | 3.440 | 18.30 | 1 | 0 | 4 | 4 |
10 | Merc 280C | 17.8 | 6 | 167.6 | 123 | 3.92 | 3.440 | 18.90 | 1 | 0 | 4 | 4 |
11 | Merc 450SE | 16.4 | 8 | 275.8 | 180 | 3.07 | 4.070 | 17.40 | 0 | 0 | 3 | 3 |
12 | Merc 450SL | 17.3 | 8 | 275.8 | 180 | 3.07 | 3.730 | 17.60 | 0 | 0 | 3 | 3 |
13 | Merc 450SLC | 15.2 | 8 | 275.8 | 180 | 3.07 | 3.780 | 18.00 | 0 | 0 | 3 | 3 |
14 | Cadillac Fleetwood | 10.4 | 8 | 472.0 | 205 | 2.93 | 5.250 | 17.98 | 0 | 0 | 3 | 4 |
15 | Lincoln Continental | 10.4 | 8 | 460.0 | 215 | 3.00 | 5.424 | 17.82 | 0 | 0 | 3 | 4 |
16 | Chrysler Imperial | 14.7 | 8 | 440.0 | 230 | 3.23 | 5.345 | 17.42 | 0 | 0 | 3 | 4 |
17 | Fiat 128 | 32.4 | 4 | 78.7 | 66 | 4.08 | 2.200 | 19.47 | 1 | 1 | 4 | 1 |
18 | Honda Civic | 30.4 | 4 | 75.7 | 52 | 4.93 | 1.615 | 18.52 | 1 | 1 | 4 | 2 |
19 | Toyota Corolla | 33.9 | 4 | 71.1 | 65 | 4.22 | 1.835 | 19.90 | 1 | 1 | 4 | 1 |
20 | Toyota Corona | 21.5 | 4 | 120.1 | 97 | 3.70 | 2.465 | 20.01 | 1 | 0 | 3 | 1 |
21 | Dodge Challenger | 15.5 | 8 | 318.0 | 150 | 2.76 | 3.520 | 16.87 | 0 | 0 | 3 | 2 |
22 | AMC Javelin | 15.2 | 8 | 304.0 | 150 | 3.15 | 3.435 | 17.30 | 0 | 0 | 3 | 2 |
23 | Camaro Z28 | 13.3 | 8 | 350.0 | 245 | 3.73 | 3.840 | 15.41 | 0 | 0 | 3 | 4 |
24 | Pontiac Firebird | 19.2 | 8 | 400.0 | 175 | 3.08 | 3.845 | 17.05 | 0 | 0 | 3 | 2 |
25 | Fiat X1-9 | 27.3 | 4 | 79.0 | 66 | 4.08 | 1.935 | 18.90 | 1 | 1 | 4 | 1 |
26 | Porsche 914-2 | 26.0 | 4 | 120.3 | 91 | 4.43 | 2.140 | 16.70 | 0 | 1 | 5 | 2 |
27 | Lotus Europa | 30.4 | 4 | 95.1 | 113 | 3.77 | 1.513 | 16.90 | 1 | 1 | 5 | 2 |
28 | Ford Pantera L | 15.8 | 8 | 351.0 | 264 | 4.22 | 3.170 | 14.50 | 0 | 1 | 5 | 4 |
29 | Ferrari Dino | 19.7 | 6 | 145.0 | 175 | 3.62 | 2.770 | 15.50 | 0 | 1 | 5 | 6 |
30 | Maserati Bora | 15.0 | 8 | 301.0 | 335 | 3.54 | 3.570 | 14.60 | 0 | 1 | 5 | 8 |
31 | Volvo 142E | 21.4 | 4 | 121.0 | 109 | 4.11 | 2.780 | 18.60 | 1 | 1 | 4 | 2 |
date = ['2022-03-01', '2022-03-02', '2022-03-03', '2022-03-04', '2022-03-05', '2022-03-06', '2022-03-07', '2022-03-08', '2022-03-09', '2022-03-10', '2022-03-11', '2022-03-12', '2022-03-13', '2022-03-14', '2022-03-01', '2022-03-02', '2022-03-03', '2022-03-04', '2022-03-05', '2022-03-06', '2022-03-07', '2022-03-08', '2022-03-09', '2022-03-10', '2022-03-11', '2022-03-12', '2022-03-13', '2022-03-14', '2022-03-15']
fz = ['A组', 'A组', 'A组', 'A组', 'A组', 'A组', 'A组', 'A组', 'A组', 'A组', 'A组', 'A组', 'A组', 'A组', 'B组', 'B组', 'B组', 'B组', 'B组', 'B组', 'B组', 'B组', 'B组', 'B组', 'B组', 'B组', 'B组', 'B组', 'B组']
zhv = [0.0205, 0.02475, 0.02843, 0.03009, 0.03211, 0.04395, 0.04487, 0.04671, 0.04663, 0.04847, 0.05031, 0.05223, 0.05307, 0.05483, 0.0326, 0.0334, 0.0333, 0.03567, 0.03659, 0.03551, 0.03935, 0.04027, 0.04033, 0.04079, 0.04255, 0.04539, 0.04915, 0.05099, 0.05291]
df = pd.DataFrame(data={"日期":date,"分组":fz,"转化率":zhv})
df
日期 | 分组 | 转化率 | |
---|---|---|---|
0 | 2022-03-01 | A组 | 0.02050 |
1 | 2022-03-02 | A组 | 0.02475 |
2 | 2022-03-03 | A组 | 0.02843 |
3 | 2022-03-04 | A组 | 0.03009 |
4 | 2022-03-05 | A组 | 0.03211 |
5 | 2022-03-06 | A组 | 0.04395 |
6 | 2022-03-07 | A组 | 0.04487 |
7 | 2022-03-08 | A组 | 0.04671 |
8 | 2022-03-09 | A组 | 0.04663 |
9 | 2022-03-10 | A组 | 0.04847 |
10 | 2022-03-11 | A组 | 0.05031 |
11 | 2022-03-12 | A组 | 0.05223 |
12 | 2022-03-13 | A组 | 0.05307 |
13 | 2022-03-14 | A组 | 0.05483 |
14 | 2022-03-01 | B组 | 0.03260 |
15 | 2022-03-02 | B组 | 0.03340 |
16 | 2022-03-03 | B组 | 0.03330 |
17 | 2022-03-04 | B组 | 0.03567 |
18 | 2022-03-05 | B组 | 0.03659 |
19 | 2022-03-06 | B组 | 0.03551 |
20 | 2022-03-07 | B组 | 0.03935 |
21 | 2022-03-08 | B组 | 0.04027 |
22 | 2022-03-09 | B组 | 0.04033 |
23 | 2022-03-10 | B组 | 0.04079 |
24 | 2022-03-11 | B组 | 0.04255 |
25 | 2022-03-12 | B组 | 0.04539 |
26 | 2022-03-13 | B组 | 0.04915 |
27 | 2022-03-14 | B组 | 0.05099 |
28 | 2022-03-15 | B组 | 0.05291 |
#折线图
(ggplot(df, aes(x='日期', y='转化率', group='分组', color='分组'))
+geom_line(size=1)
+scale_x_date(name='日期', breaks='2 weeks') #解决x轴标签覆盖问题
+scale_fill_hue(s=0.90, l=0.65, h=0.0417, color_space='husl') #自动配色
+xlab('时间') #重命名x轴名称
+ylab('CVR') #重命名y轴名称
+ggtitle('AB组活动转化率趋势图')
+theme_matplotlib()
+theme(legend_position = 'right',text=element_text(family='SimHei'))
)
D:\app-soft\anaconda\lib\site-packages\plotnine\guides\guides.py:187: PlotnineWarning: Cannot generate legend for the 'fill' aesthetic. Make sure you have mapped a variable to it
<ggplot: (150994698292)>
再做一个折线图下的面积图。
#折线下面积图
(ggplot(df, aes(x='日期', y='转化率', group='分组'))
+geom_area(aes(fill='分组'), alpha=0.75, position='identity')
+geom_line(aes(color='分组'), size=0.75)
+scale_x_date(name='日期', breaks='3 days') # x轴日期标签间隔
+scale_fill_hue(s=0.90, l=0.65, h=0.0417, color_space='husl')
+xlab('时间') +ylab('CVR')
+ggtitle('AB组活动转化率趋势图')
+theme_matplotlib()
+theme(legend_position = 'right',text=element_text(family='SimHei'))
)
<ggplot: (150862060442)>
为做夹层面图先做数据准备,如求出ymin和ymax。(求df两列中各行最大最小值)
#折线之间夹面积图/夹层填充面积
df_A = df[df['分组'] == 'A组']
df_B = df[df['分组'] == 'B组']
df_new = pd.merge(df_A, df_B, how='left', on='日期', suffixes=('A组', 'B组'))
df_new['最小值'] = df_new.apply(lambda x: x[['转化率A组', '转化率B组']].min(), axis=1)#求两列中各行最大最小值
df_new['最大值'] = df_new.apply(lambda x: x[['转化率A组', '转化率B组']].max(), axis=1)
#df_new['比较'] = df_new.apply(lambda x: 'A组高' if x['转化率A组'] - x['转化率B组'] > 0 else 'B组高', axis=1)
df_new['ymin1'] = df_new['最小值']
df_new.loc[(df_new['转化率A组']-df_new['转化率B组']) > 0, 'ymin1'] = np.nan
df_new['ymin2'] = df_new['最小值']
df_new.loc[(df_new['转化率A组']-df_new['转化率B组']) <= 0, 'ymin2'] = np.nan
df_new['ymax1'] = df_new['最大值']
df_new.loc[(df_new['转化率A组']-df_new['转化率B组']) > 0, 'ymax1'] = np.nan
df_new['ymax2'] = df_new['最大值']
df_new.loc[(df_new['转化率A组']-df_new['转化率B组']) <= 0, 'ymax2'] = np.nan
①最大值、最小值:用于绘制夹层的填充线;
②之所以ymin1/ymax1 与 ymin2/ymax2 区分开,是为了区分填充线颜色
③之所以绘制两次ribbon除了原因②之外,也是为了避免出现多余的填充
w = (ggplot()
+geom_ribbon(df_new, aes(x='日期', ymin='ymin1', ymax='ymax1', group=1), alpha=0.5, fill='#00B2F6', color='none')
+geom_ribbon(df_new, aes(x='日期', ymin='ymin2', ymax='ymax2', group=1), alpha=0.5, fill='#FF6B5E', color='none')
+geom_line(df, aes(x='日期', y='转化率', group='分组', color='分组'), size=1)
+scale_x_date(name='日期', breaks='3 days')
+theme_matplotlib()
+theme(legend_position = 'right',text=element_text(family='SimHei'))
)#原文链接:https://blog.csdn.net/weixin_45881406/article/details/124902333
w
<ggplot: (150862100342)>
png_path = r"c:\Users\yubg\Desktop\yubg.png"
w.save(filename=png_path,width=200,height=150,units='mm',dpi=1000)
D:\app-soft\anaconda\lib\site-packages\plotnine\ggplot.py:718: PlotnineWarning: Saving 200.0 x 150.0 mm image. D:\app-soft\anaconda\lib\site-packages\plotnine\ggplot.py:719: PlotnineWarning: Filename: c:\Users\yubg\Desktop\yubg.png