You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现每个y轴支持多列的多坐标轴pandas DataFrame绘图功能

多Y轴共享绘图函数实现方案

直接上可运行的完整实现代码:

import pandas as pd
import matplotlib.pyplot as plt
from typing import List

def plot_df(df: pd.DataFrame, x_column: str, columns: List[List[str]]):
    """Plot DataFrame using `x_column` on the x-axis and `len(columns)` different
    y-axes where the axis numbered `i` is calibrated to render the columns in `columns[i]`.

    核心要求:
    1. 全图仅保留1个图例
    2. 每个列对应的绘图线条使用不同的颜色
    坐标轴可匹配对应分组下任意一个线条的颜色,并关联对应分组标签(比如价格轴、收益率轴、增长率轴)
    """
    # 预生成足够多的唯一颜色,默认使用tab20调色板最多支持20个不同列,可按需替换其他调色板
    all_columns = [col for group in columns for col in group]
    colors = plt.cm.tab20.colors[:len(all_columns)]
    color_map = dict(zip(all_columns, colors))
    
    fig, host_ax = plt.subplots(figsize=(10,6))
    axes = [host_ax]
    all_handles = []
    
    # 额外的y轴向右偏移,避免重叠
    offset = 60
    for i, group in enumerate(columns):
        # 第一个组用host轴,其余生成twinx轴
        if i > 0:
            ax = host_ax.twinx()
            # 超过第二个的轴需要向右移动位置
            if i > 1:
                ax.spines.right.set_position(("axes", 1 + (i-1)*offset/100))
            axes.append(ax)
        else:
            ax = host_ax
        
        # 绘制当前分组下的所有列,每个列用唯一颜色
        for col in group:
            line, = ax.plot(df[x_column], df[col], color=color_map[col], label=col)
            all_handles.append(line)
        
        # 坐标轴用分组第一个列的颜色匹配,设置轴标签
        group_first_col = group[0]
        ax.set_ylabel(f"{group_first_col}组轴", color=color_map[group_first_col])
        ax.tick_params(axis='y', colors=color_map[group_first_col])
    
    # 全局仅保留一个图例
    host_ax.legend(handles=all_handles, loc='upper left')
    # 调整布局避免轴标签被截断
    fig.tight_layout()
    plt.show()

核心逻辑说明

  • 提前为所有需要绘制的列分配全局唯一的颜色,从根源避免同色冲突
  • 同一分组的列全部绘制在同一个twinx生成的坐标轴上,每个坐标轴独立校准刻度范围,互不影响
  • 所有线条的图例句柄统一收集后,由主坐标轴生成唯一的全局图例,避免多图例重复
  • 坐标轴颜色默认匹配分组第一个列的线条颜色,可按需修改为分组内任意列的颜色

测试用例

你给出的示例可直接运行测试:

# 构造测试数据
import numpy as np
dates = pd.date_range(start='2023-01-01', periods=100)
df = pd.DataFrame({
    'time': dates,
    'price1': np.cumsum(np.random.randn(100)) + 100,
    'price2': np.cumsum(np.random.randn(100)) + 200,
    'returns': np.random.randn(100)*0.05,
    'growth': np.cumsum(np.random.randn(100)) + 10
})

# 调用函数
plot_df(df, 'time', [['price1', 'price2'], ['returns'], ['growth']])

运行后会生成符合要求的3个Y轴图表,price1和price2共享第一个Y轴,returns和growth分别使用独立的第二、第三个Y轴,所有线条颜色唯一,全局只有一个图例。

内容的提问来源于stack exchange,提问作者Peteris

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 12:57:02