Seaborn按年月绘制受害人数量折线图及FacetGrid使用问题咨询
问题根因总述
你遇到的两个问题本质上都和x轴month字段的类型、以及seaborn绘图的默认坐标轴共享规则有关:
问题1:单图x轴月份不按1-12顺序排序的解决方法
出现这个问题的核心原因是month字段大概率是字符串类型,seaborn会默认按照字符串出现的先后顺序排序,而非数字顺序。你可以选择以下两种方法之一修复:
- 方法1:将
month字段转换为有序分类类型,明确指定顺序
import pandas as pd # 如果你的month是数值类型,用这行代码 number_victims['month'] = pd.Categorical(number_victims['month'], categories=range(1,13), ordered=True) # 如果你的month是字符串类型,用这行代码 number_victims['month'] = pd.Categorical(number_victims['month'], categories=[str(i) for i in range(1,13)], ordered=True)
转换完成后再运行你原来的lineplot代码,x轴就会自动按1-12的顺序排列,顺带提一句你原代码里legend的title写错了,应该是title='年份'而非title='month'。
- 方法2:绘图后手动指定x轴刻度
sb.lineplot(data=number_victims, x='month', y='victims', hue='year') plt.xticks(ticks=range(1,13), labels=range(1,13)) # 强制设置x轴刻度为1-12 plt.legend(loc='center left', bbox_to_anchor=(1, 0.5), title = '年份', title_fontsize = 12)
问题2:分面图异常的原因及修复方法
两个异常的原因分别是:
- 2016年分面从1月开始而不是7月:因为
FacetGrid默认开启了sharex=True,也就是所有分面共享相同的x轴范围,2017年的月份范围是1-12,所以2016年的x轴范围也被同步为1-12,哪怕没有1-6月的数据。 - x轴只显示1-10:是seaborn/matplotlib的自动刻度适配逻辑,当图表宽度不够时会自动跳过部分刻度避免重叠。
修复方法如下,只需要修改你原来的FacetGrid代码,先做month字段的有序分类转换,再调整参数即可:
# 先保证month的顺序正确 number_victims['month'] = pd.Categorical(number_victims['month'], categories=range(1,13), ordered=True) # 初始化FacetGrid时加入sharex=False,关闭x轴共享 g = sb.FacetGrid(number_victims, col="year", margin_titles=True, col_wrap=3, height=3, aspect=2, sharex=False) g.map_dataframe( sb.lineplot, x="month", y="victims" ) # 强制给所有分面设置x轴刻度为1-12,避免自动省略 g.set(xticks=range(1,13), xticklabels=range(1,13)) g.fig.subplots_adjust(top=0.8) g.fig.suptitle('不同年份各月受害人数变化趋势');
如果你希望2016年的分面也显示完整1-12月、空出1-6月的位置,只需要把sharex=False改回sharex=True,保留set(xticks=...)的代码即可。
内容的提问来源于stack exchange,提问作者Asma
相关产品推荐
相关产品推荐

