python - 如何修复 matplotlib 中所有子图的图例和主标题?
问题描述
我是 Python 新手,我一直在使用虚拟数据集来练习 Python。以前我在生成子图、然后绘制频率和比例 % 时遇到了麻烦,但现在我今天已经克服了它们。现在,我正在努力修复一些化妆品,尤其是传说和情节标题。
这是生成整个虚拟数据集的可重现代码:
d = {
'SeniorCitizen': [0,1,0,0,0,0,0,1,0,1,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0] ,
'CollegeDegree': [0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1] ,
'Married': [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1] ,
'FulltimeJob': [1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,0,0,1,1,0,0,0,1] ,
'DistancefromBranch': [7,9,14,20,21,12,22,25,9,9,9,12,13,14,16,25,27,4,14,14,20,19,15,23,2] ,
'ReversedPayment': [0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,1,0,1,0,0,1,0,1,0] }
CarWash = pd.DataFrame(data = d)
categoricals = ['SeniorCitizen','CollegeDegree','Married','FulltimeJob','ReversedPayment']
numerical = ['DistancefromBranch']
CarWash[categoricals] = CarWash[categoricals].astype('category')
下面是我尝试生成频率和比例 %,以进行并排比较:
plt.suptitle("Distribution of target variable across the categorical variables - frequencies # and proportions %")
nrow = 1
ncol = len(categoricals[:-1])
figure, axes = plt.subplots(nrow,ncol, figsize = (40,10))
for i,ax in zip(categoricals[:-1],axes.flatten()):
# plots frequencies
CarWash.groupby([i,'ReversedPayment']).size().reset_index().pivot(index = i,columns = 'ReversedPayment').plot(kind = 'bar', stacked = True, ax = ax, sharey=True)
ax.tick_params(axis='both', labelsize = 25, labelrotation = 0)
ax.set_title(i,fontsize = 30)
ax.set_xlabel("")
#ax.get_legend().remove()
# labels data
for p in ax.patches:
x_adjust = 0.25
value = p.get_height()
X = p.get_x() + x_adjust
Y = p.get_y() + p.get_height()/2
XY = (X,Y)
if value != 0:
ax.annotate(int(value),XY,fontsize = 25)
nrow = 1
ncol = len(categoricals[:-1])
figure, axes = plt.subplots(nrow,ncol, figsize = (40,10))
for i,ax in zip(categoricals[:-1],axes.flatten()):
# plots proportions
CarWash.groupby([i,'ReversedPayment']).size().reset_index().pivot(index = i, columns = 'ReversedPayment').apply(lambda x: x/x.sum(),axis=1).plot(kind = 'bar', stacked = True, ax = ax)
ax.tick_params(axis='both', labelsize = 25, labelrotation = 0)
ax.set_title(i,fontsize = 30)
ax.set_xlabel("")
#ax.get_legend().remove()
# labels data
for p in ax.patches:
x_adjust = 0.25/3
value = p.get_height()
X = p.get_x() + x_adjust
Y = p.get_y() + p.get_height()/2
XY = (X,Y)
if value != 0:
ax.annotate(str(round(value*100,1)) + "%",XY,fontsize = 25)
下面是我的输出:
所以,我对化妆品编码的问题是:
- 标题:我尝试使用一个主标题,
plt.suptitle()
但它没有按预期工作(我看不到任何输出)。还尝试了其他事情,但其他一切都引发了错误。 - 图例:图例看起来很难看,我不需要它们用于所有子情节。我正在尝试为所有子图只获取一个图例,这将非常棒并且可以节省空间。我尝试了类似的东西,
plt.legend([CarWash[i],CarWash['ReversedPayment']], ['Blue', 'Orange'])
但没有奏效。
任何意见/建议都非常受欢迎,非常感谢。谢谢你。
解决方案
您plt.suptitle
在为绘图创建图形之前执行,这就是标题没有出现在最终绘图中的原因。有关如何为多个子图创建公共图例的答案,请参见此处。综合考虑,您可以尝试以下方法:
nrow = 2
ncol = len(categoricals[:-1])
fig, axes = plt.subplots(nrow,ncol, figsize = (40,20))
plt.suptitle("Distribution of target variable across the categorical variables - frequencies # and proportions %", size=40, y=1.01)
for i,ax in zip(categoricals[:-1],axes.flatten()):
# plots frequencies
df = CarWash[[i,'ReversedPayment']].value_counts().unstack().fillna(0)
ax.bar(df.index, df[0], label='0')
ax.bar(df.index, df[1], bottom=df[0], label='1')
ax.tick_params(axis='both', labelsize = 25, labelrotation = 0)
ax.set_title(i,fontsize = 30, y=1.05)
ax.set_xticks([0,1])
# labels data
for p in ax.patches:
x_adjust = 0.35
value = p.get_height()
X = p.get_x() + x_adjust
Y = p.get_y() + p.get_height()/2
XY = (X,Y)
if value != 0:
ax.annotate(int(value),XY,fontsize = 25)
for i,ax in zip(categoricals[:-1],axes.flatten()[ncol:]):
# plots proportions
df = CarWash[[i,'ReversedPayment']].value_counts().unstack().fillna(0)
df = (df.T/df.T.sum()).T*100
ax.bar(df.index, df[0], label='0')
ax.bar(df.index, df[1], bottom=df[0], label='1')
ax.tick_params(axis='both', labelsize = 25, labelrotation = 0)
ax.set_title(i,fontsize = 30, y=1.05)
ax.set_xticks([0,1])
ax.set_ylim(0,110)
# labels data
for p in ax.patches:
x_adjust = 0.25
value = p.get_height()
X = p.get_x() + x_adjust
Y = p.get_y() + p.get_height()/2
XY = (X,Y)
if value != 0:
ax.annotate(str(round(value,1)) + "%",XY,fontsize = 25)
plt.subplots_adjust(hspace=0.4)
# plot legend
handles, labels = ax.get_legend_handles_labels()
fig.legend(handles, labels, loc=(0.95, 0.1), prop={'size': 30})
plt.show()
它给:
推荐阅读
- c++ - 用另一个元素替换字符串中的元素的函数
- python - 按 char 和 int 拆分列表
- r - 根据列的唯一值动态创建单选按钮 - Shiny
- rest - Katalon Studio:将响应分配给全局变量
- python - 在 buildozer 上下载 pywin32
- imagemagick - 用透明度填充图像,使其大小在两个方向上都是 300 的倍数(ImageMagick 7)
- react-native - react-native 项目运行时出现 gradle 错误,Windows 10
- elasticsearch - alpakka elasticsearch中的自定义重试行为
- python - 如何从开头和结尾删除空格?分词器(split='[.!?]')
- visual-studio-2019 - 找不到包 Microsoft.AspNetCore.Components.WebAssembly