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

在带MultiIndex的Pandas折线图中添加竖线并控制X轴标签

MultiIndex DataFrame 绘图问题解决方案

针对给定的MultiIndex(date+rank)结构的DataFrame,以下是两个绘图需求的具体解决方案:


问题1:在MultiIndex X轴指定位置添加竖线

问题根源

直接使用(date, rank)格式的MultiIndex元组作为竖线位置时,matplotlib无法识别该格式,因此抛出ConversionError。正确做法是将MultiIndex位置转换为DataFrame对应的行索引序号(即数据在表格中的行号)。

实现代码

import pandas as pd
import matplotlib.pyplot as plt

# 初始化数据
dx = pd.DataFrame({
    "date": [
        pd.to_datetime('2025-02-24'), pd.to_datetime('2025-02-24'), pd.to_datetime('2025-02-24'), pd.to_datetime('2025-02-24'),
        pd.to_datetime('2025-02-25'), pd.to_datetime('2025-02-25'), pd.to_datetime('2025-02-25'), 
        pd.to_datetime('2025-02-26'), pd.to_datetime('2025-02-26'), pd.to_datetime('2025-02-26'), pd.to_datetime('2025-02-26'), pd.to_datetime('2025-02-26')
    ],
     "rank": [0.0,1.0,2.0,100.0,0.0,1.0,100.0,0.0,1.0,2.0,3.0,100.0],
    "value": [2.3, 2.5, 2.4, 2.36, 2.165, 2.54, 2.34, 2.12, 2.32, 2.43, 2.4, 2.3]
})
dx.set_index(["date", "rank"], inplace=True)

# 创建绘图对象
fig, ax = plt.subplots()
dx['value'].plot(ax=ax)

# 筛选rank=1和rank=100的MultiIndex位置
rank1_indices = dx.index[dx.index.get_level_values('rank') == 1.0]
rank100_indices = dx.index[dx.index.get_level_values('rank') == 100.0]

# 绘制rank=1的红色虚线竖线
for idx_tuple in rank1_indices:
    row_pos = dx.index.get_loc(idx_tuple)
    ax.axvline(x=row_pos, color='red', linestyle='--', alpha=0.7)

# 绘制rank=100的蓝色点线竖线
for idx_tuple in rank100_indices:
    row_pos = dx.index.get_loc(idx_tuple)
    ax.axvline(x=row_pos, color='blue', linestyle=':', alpha=0.7)

plt.tight_layout()
plt.show()

关键说明

  • dx.index.get_loc(idx_tuple):将MultiIndex元组转换为对应的行号,matplotlib可直接用该数值作为x轴坐标。
  • 通过alpha参数调整竖线透明度,避免遮挡折线数据。

问题2:仅显示rank=0的X轴标签

实现思路

遍历X轴所有刻度对应的MultiIndex项,仅保留rank=0的标签文本,其余标签设为空字符串,从而实现只显示目标标签的效果。

实现代码

# 接上述绘图代码,在绘制竖线后添加以下逻辑
# 获取当前X轴的刻度与标签
ticks = ax.get_xticks()
new_labels = []

for tick_pos in ticks:
    # 获取刻度对应的MultiIndex元组
    current_idx = dx.index[int(tick_pos)]
    # 仅保留rank=0的日期标签,其余设为空
    if current_idx[1] == 0.0:
        new_labels.append(current_idx[0].strftime('%Y-%m-%d'))
    else:
        new_labels.append("")

# 更新X轴标签
ax.set_xticklabels(new_labels)
# 可选:旋转标签避免重叠
plt.xticks(rotation=45)

plt.tight_layout()
plt.show()

关键说明

  • current_idx[0].strftime('%Y-%m-%d'):将日期格式化为易读的字符串,可根据需求调整格式。
  • 无需依赖旋转标签的“曲线救国”方式,直接通过控制标签内容实现需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 01:23:18