人口金字塔负X轴处理:移除负标签或重命名为正值的方法
解决人口金字塔的两个X轴可视化需求
首先得说下,你的原始代码目前是把两组性别数据都画在正X轴方向,还没实现人口金字塔左右分置的效果,所以咱们先把这个基础调整好,再处理你提出的两个X轴问题。
第一步:重构代码实现人口金字塔左右布局
人口金字塔的核心是让其中一组(比如男性)的数值取负,这样会显示在X轴左侧,另一组(女性)保留正值在右侧:
import matplotlib.pyplot as plt import seaborn as sns plt.figure(figsize=(13,10), dpi=80) group_col = 't1_gender' order_of_bars = df.agegroup.unique()[::-1] colors = [plt.cm.Spectral(i/float(len(df[group_col].unique())-1)) for i in range(len(df[group_col].unique()))] # 分性别绘制左右两侧的柱状图 for c, group in zip(colors, df[group_col].unique()): group_data = df.loc[df[group_col]==group, :] # 给第一组(比如男性)的count取负,放到左侧 if group == df[group_col].unique()[0]: sns.barplot(x=-group_data['count'], y='agegroup', data=group_data, order=order_of_bars, color=c, label=group) else: sns.barplot(x='count', y='agegroup', data=group_data, order=order_of_bars, color=c, label=group) # 基础可视化装饰 plt.xlabel("Number of calls") plt.ylabel("Age group") plt.yticks(fontsize=12) plt.title("Call Volume Population Pyramid by Age Group", fontsize=22) plt.legend()
需求1:移除负X轴的刻度标签
要隐藏左侧的负X轴标签,我们可以筛选出非负的刻度值,只保留这些刻度的显示:
# 在plt.legend()之后添加这段代码 # 获取当前所有X轴刻度 xticks = plt.xticks()[0] # 只保留大于等于0的刻度 valid_xticks = [tick for tick in xticks if tick >= 0] # 更新刻度和对应的标签 plt.xticks(valid_xticks, [str(int(tick)) for tick in valid_xticks])
这样左侧的负刻度就不会显示任何标签了,只保留右侧的正值刻度标签。
需求2:将负X轴的数值重命名为正值
如果希望左侧的负刻度显示成对应的正数(比如-80显示为80),我们可以自定义刻度标签,把负数转为绝对值显示:
# 在plt.legend()之后添加这段代码 xticks = plt.xticks()[0] # 把每个刻度值转为绝对值后作为标签 xtick_labels = [str(int(abs(tick))) for tick in xticks] plt.xticks(xticks, xtick_labels)
这样左右两侧的刻度都会显示为正数,完全符合人口金字塔的常规展示方式。
完整代码(以需求2为例)
把所有逻辑整合后的完整代码,还修复了原代码中ax.get_facecolor()的错误(原代码未定义ax,改用plt.gca()获取当前坐标轴):
import matplotlib.pyplot as plt import seaborn as sns plt.figure(figsize=(13,10), dpi=80) group_col = 't1_gender' order_of_bars = df.agegroup.unique()[::-1] colors = [plt.cm.Spectral(i/float(len(df[group_col].unique())-1)) for i in range(len(df[group_col].unique()))] # 绘制左右分置的人口金字塔 for c, group in zip(colors, df[group_col].unique()): group_data = df.loc[df[group_col]==group, :] if group == df[group_col].unique()[0]: sns.barplot(x=-group_data['count'], y='agegroup', data=group_data, order=order_of_bars, color=c, label=group) else: sns.barplot(x='count', y='agegroup', data=group_data, order=order_of_bars, color=c, label=group) # 基础装饰 plt.xlabel("Number of calls") plt.ylabel("Age group") plt.yticks(fontsize=12) plt.title("Call Volume Population Pyramid by Age Group", fontsize=22) plt.legend() # 处理需求2:将负X轴显示为正值 xticks = plt.xticks()[0] xtick_labels = [str(int(abs(tick))) for tick in xticks] plt.xticks(xticks, xtick_labels) # 保存图片(修复ax未定义的问题) plt.savefig('images/figure2.png', dpi=300, facecolor=plt.gca().get_facecolor(), transparent=True, pad_inches=0.0) plt.show()
内容的提问来源于stack exchange,提问作者Sanch
相关产品推荐
相关产品推荐

