使用的基本框架模式如下,各种功能用“+”连接叠加,最后用一个完整的括号()首位包裹起来。
( ggplot(df,aes()) + geom_xx())+ scale_xx() + theme() + …)
必选:(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两列做条形图。
#创建/导入数据
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
)
#开始画图
(ggplot(data, aes(x='name',y='price')) + geom_bar(stat='identity'))
# stat=identity表示用数据表原有的数据进行统计,见图1。也可用geom_col()函数画柱状图,不需stat参数
p =(ggplot(data, aes(x='name',y='price',fill='name'))+geom_bar(stat='identity')) #见图2
print(p)
从图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()更像传统意义的柱状图绘制方法
3、绘图¶
上面已经使用函数geom_bar()简单的实现了条形图的画法,并在映射aes里面添加参数fill对条形块填充不同的颜色,还使用函数coord_flip()对轴进行旋转。但是图形上还缺少很多元素,如每个条形块上的数据标签、条形的宽度粗细和轴上的数据排序等。
1)添加数据标签
对每个条形块上进行数据标注,可使用geom_text()函数来实现,需要给函数参数aes,其中label表示要标注的数据来源。比如在每个条形块的上方标注数据。续接上面的代码。
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)
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轴显示范围进行设置。
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绘图语句中添加主题参数(后带括号),一般在绘图的格式结束之后添加。
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
#按照给定的范围以及间隔,显示完整坐标刻度。
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
t = (ggplot(data,aes(x='totle',y='price',fill="place",color="place"))+ geom_line(size=1))
t + geom_point(aes(shape='place')) #设置不同的标记,见图17
stat_smooth拟合数据。参数method默认值为'auto',可用的方法有:
'auto' #if(n<1000)则使用loess,否则使用glm
'lm','ols' #线性模型
'wls' #加权线性模型
'rlm' #鲁棒线性模型
'glm' #广义线性模型
'gls' #广义最小二乘
'lowess' #局部加权回归(简单)
'loess' #局部加权回归
'mavg' #移动平均值
'gpr' #高斯过程回归器
from plotnine.data import mtcars
(ggplot(mtcars, aes('wt', 'mpg', color='factor(gear)'))
+ geom_point()
+ stat_smooth(method='lm')
+ facet_wrap('~gear'))
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})
(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'))
#折线下面积图
(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'))
#折线之间夹面积图/夹层填充面积
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
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
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