pd.DataFrame.plot使用secondary_y时如何修改图例字号并完整显示列名
问题原因
调用pd.DataFrame.plot()传入secondary_y参数启用次坐标轴时,会生成两个独立的坐标轴实例:主Y轴承载未指定到次轴的数据列,次Y轴承载secondary_y参数指定的列。此时如果对plot()的返回值直接链式调用.legend(),仅能读取主坐标轴上的绘图序列,因此只会展示主Y轴对应的列名,次坐标轴的列会被遗漏。
未传入secondary_y时只有一个坐标轴实例,链式调用.legend()可以捕获所有数据列,因此不会出现图例缺失问题。
复现验证
启用次坐标轴时图例缺失场景
import pandas as pd import numpy as np np.random.seed(42) df = pd.DataFrame(np.random.randn(24*3, 2), index=pd.date_range('1/1/2019', periods=24*3, freq='h')) df.columns = ['A', 'B'] # 该写法仅会显示主Y轴的列A,列B的图例丢失 df.plot(secondary_y = ["B"], figsize=(12,5)).legend(fontsize=20, loc="upper right")
单坐标轴正常场景
import pandas as pd import numpy as np np.random.seed(42) df = pd.DataFrame(np.random.randn(24*3, 2), index=pd.date_range('1/1/2019', periods=24*3, freq='h')) df.columns = ['A', 'B'] # 单轴下图例可正常展示A、B两列 df.plot(figsize=(12,5)).legend(fontsize=20, loc="upper right")
解决方案
推荐使用手动合并主次轴图例句柄的方式,兼容性最好,不会和其他子图配置冲突:
import pandas as pd import numpy as np np.random.seed(42) df = pd.DataFrame(np.random.randn(24*3, 2), index=pd.date_range('1/1/2019', periods=24*3, freq='h')) df.columns = ['A', 'B'] # 先获取主坐标轴对象 ax = df.plot(secondary_y=["B"], figsize=(12,5)) # 分别提取主、次坐标轴的图例句柄和标签 handles_main, labels_main = ax.get_legend_handles_labels() handles_secondary, labels_secondary = ax.right_ax.get_legend_handles_labels() # 合并后统一设置图例样式,可正常调整字号、位置等参数 ax.legend( handles_main + handles_secondary, labels_main + labels_secondary, fontsize=20, loc="upper right" )
运行上述代码后,图例可完整展示A、B两个列名,同时字号修改会对所有图例项生效。
如果是单图不存在子图干扰的场景,也可以直接调用matplotlib的全局图例接口,自动收集所有坐标轴的绘图元素:
import pandas as pd import numpy as np import matplotlib.pyplot as plt np.random.seed(42) df = pd.DataFrame(np.random.randn(24*3, 2), index=pd.date_range('1/1/2019', periods=24*3, freq='h')) df.columns = ['A', 'B'] df.plot(secondary_y = ["B"], figsize=(12,5)) # 全局接口自动收集所有轴的图例项 plt.legend(fontsize=20, loc="upper right")
内容的提问来源于stack exchange,提问作者Eiffelbear
相关产品推荐
相关产品推荐

