x轴使用datetime类型变量时叠加于柱状图的折线图无法显示问题
问题描述
我尝试绘制一张叠加两条折线图的柱状图,柱状图可正常显示,但始终无法将折线绘制在柱状图上方,所用代码如下:
fig, ax = plt.subplots(figsize=(18,9)) sns.set_style("darkgrid") g=sns.barplot(date_new, df["Net xG (xG - Opponent's xG)"].astype("float"), palette="coolwarm_r", hue=df["Net xG (xG - Opponent's xG)"].replace({"-":0}).astype("float"), dodge=False, data=df) plt.plot(date_new, -df["Opponent's xG"].astype("float"), color="gold", marker="o") plt.plot(date_new, df["xG (Expected goals)"].astype("float"), color="indianred", marker="o") g.set_xticklabels(stuff[::-1], rotation=90) g.get_legend().remove() g.set(xlim=([-0.8, 46])) plt.show()
x轴所用的date_new变量为datetime64[ns]格式。我发现如果通过date_new.astype("str")将其转为字符串格式,折线图可正常显示,但x轴的日期顺序是颠倒的。
我尝试将x轴变量改为date_new[::-1]来反转日期排序,但折线的显示顺序并未发生变化。
原因说明
该异常是seaborn柱状图和matplotlib折线图的x轴坐标处理逻辑不匹配导致的:
- seaborn的barplot属于分类图表,不管输入的x轴是日期还是其他格式,都会自动把每个x值当成独立分类,对应的x轴实际坐标是从0开始的连续整数,和日期本身的数值大小无关
- matplotlib的plot函数遇到datetime格式的x值时,会把日期转换为时间戳浮点数来计算坐标位置,和barplot的整数坐标完全不在同一个坐标系,所以折线直接跑到了画布可视区域之外,无法显示
将日期转成字符串之后,plot也会把字符串当成分类处理,坐标逻辑和barplot对齐了,所以能显示,但手动修改xticklabels顺序的操作会导致标签和实际数据对应不上,出现顺序颠倒的问题。
修复方案
直接给plot传入和barplot分类一一对应的整数位置作为x轴即可,不需要修改日期格式:
fig, ax = plt.subplots(figsize=(18,9)) sns.set_style("darkgrid") # 原有柱状图逻辑不变 g = sns.barplot( x=date_new, y=df["Net xG (xG - Opponent's xG)"].astype("float"), palette="coolwarm_r", hue=df["Net xG (xG - Opponent's xG)"].replace({"-":0}).astype("float"), dodge=False, data=df ) # 用和barplot分类一一对应的整数序列作为折线的x轴 x_coords = range(len(date_new)) plt.plot(x_coords, -df["Opponent's xG"].astype("float"), color="gold", marker="o") plt.plot(x_coords, df["xG (Expected goals)"].astype("float"), color="indianred", marker="o") # x轴标签调整逻辑不变 g.set_xticklabels(stuff[::-1], rotation=90) g.get_legend().remove() g.set(xlim=([-0.8, 46])) plt.show()
如果需要调整日期的显示顺序,直接先对date_new和对应的df数据做排序,再传入绘图函数即可,不需要单独调整折线的x轴参数。
内容的提问来源于stack exchange,提问作者onatto
相关产品推荐
相关产品推荐

