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

如何绘制按工作日着色标记的时间序列并添加对应图例?

为按工作日着色的散点图添加图例

这问题我之前也碰到过!核心原因是Matplotlib的scatter在使用c参数绑定类别时,不会自动帮你生成离散的图例,得手动处理。给你两种靠谱的解决方案:

方法一:按工作日分组绘制(最直观)

这种方法是把每个工作日的数据单独绘制散点,这样每个组会自动对应图例条目,代码可读性也高:

import matplotlib.pyplot as plt
import pandas as pd

# 假设你的DataFrame已经准备好:日期索引、Series1列、day列(如'周一'/'Monday'等类别)
# 先绘制基础折线图
plt.plot(df.index, df['Series1'], marker='o', linestyle='-', color='gray', alpha=0.5)

# 获取所有唯一的工作日类别
unique_days = df['day'].unique()

# 循环绘制每个工作日的散点
for day in unique_days:
    # 筛选当前工作日的数据
    day_data = df[df['day'] == day]
    plt.scatter(day_data.index, day_data['Series1'], label=day)

# 添加图例和其他美化设置
plt.legend(title='工作日')
plt.xlabel('日期')
plt.ylabel('Series1 数值')
plt.xticks(rotation=45)  # 旋转日期标签避免重叠
plt.tight_layout()  # 自动调整布局
plt.show()

方法二:使用颜色映射+自定义图例补丁

如果你的day列是数值类型(比如0代表周一,6代表周日),可以用这种方法,先指定颜色映射,再手动创建图例元素:

import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
import pandas as pd

# 绘制散点和折线图
scatter_plot = plt.scatter(x=df.index, y=df['Series1'], c=df['day'], cmap='viridis')
plt.plot(df.index, df['Series1'], marker='o', linestyle='-', color='gray', alpha=0.5)

# 定义工作日名称与数值的对应关系(根据你的实际情况调整)
day_mapping = {0: '周一', 1: '周二', 2: '周三', 3: '周四', 4: '周五', 5: '周六', 6: '周日'}

# 创建图例补丁:每个补丁对应一个工作日的颜色和名称
legend_handles = []
for day_num, day_name in day_mapping.items():
    # 获取对应颜色
    color = scatter_plot.cmap(scatter_plot.norm(day_num))
    # 创建补丁对象
    patch = mpatches.Patch(color=color, label=day_name)
    legend_handles.append(patch)

# 添加自定义图例
plt.legend(handles=legend_handles, title='工作日')
plt.xlabel('日期')
plt.ylabel('Series1 数值')
plt.xticks(rotation=45)
plt.tight_layout()
plt.show()

为什么原代码无法生成图例?

当你直接用plt.scatter(x=df.index, y=df['Series1'], c=df['day'])时,Matplotlib会把day的值当作连续的数值映射到颜色空间,而不是离散的类别,因此不会自动生成每个工作日对应的图例项。上面两种方法都是通过手动处理离散类别,来生成正确的图例。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 08:09:02