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

Pandas中plot.line()绘制分类数值型x轴的问题

问题

我想要创建一个折线图,x轴仅显示分类数值型的1.0、2.0、3.0这三个值,但运行以下代码后,x轴显示的是0.5-3.5的数值范围,求解决方法:

fig, axes = plt.subplots(nrows=2)
fig.tight_layout(pad=3.2)
 
newdata = newdf.groupby('smoking-number').mean().reset_index()
sem = newdf.groupby('smoking-number').sem().reset_index()
newdata.plot.line(x='smoking-number',y='distance', yerr= sem, ax=axes[0],legend=False)
newdata.plot.line(x='smoking-number',y='duration', yerr= sem, ax=axes[1],legend=False)
upperbounddistance = max(newdata[['distance']].values)+max(sem[['distance']].values)
lowerbounddistance = min(newdata[['distance']].values)-min(sem[['distance']].values)
upperboundduration = max(newdata[['duration']].values)+max(sem[['duration']].values)
lowerboundduration = min(newdata[['duration']].values)-min(sem[['duration']].values)
axes[0].set_ylim(lowerbounddistance,upperbounddistance)
axes[0].set_xlim(0.5,3.5)
axes[1].set_ylim(lowerboundduration,upperboundduration)
axes[1].set_xlim(0.5,3.5)
axes[0].set_ylabel("Wayfinding distance")
axes[0].set_xlabel("Smoking frequency")
axes[1].set_ylabel("Wayfinding duration")
axes[1].set_xlabel("Smoking frequency")

数据示例:

distance
10  48.146090
13  98.877301
17  66.670310
19  95.764316
21  78.737108
22  48.404197
25  63.910073
27  40.862231
28  50.223985
30  38.724922

duration
10  40.976006
13  90.093298
17  88.349603
19  82.737323
21  72.579054
22  40.059987
25  57.629693
27  38.419589
28  40.834470
30  34.813547

smoking-number
10  1.0
13  1.0
17  1.0
19  1.0
21  1.0
22  1.0
25  3.0
27  1.0
28  1.0
30  1.0
解决方案

问题根源有两个:一是你手动设置了xlim(0.5,3.5)强制扩展了x轴范围;二是matplotlib默认将数值型的smoking-number当作连续数值轴处理,而非分类轴。

修改步骤如下:

  1. 移除两行set_xlim(0.5,3.5)代码,取消强制范围限制
  2. 将smoking-number转换为字符串类型,让matplotlib识别为分类变量
  3. 手动指定x轴刻度和标签,确保只显示1.0、2.0、3.0三个值

修改后的完整代码:

import matplotlib.pyplot as plt
import pandas as pd

fig, axes = plt.subplots(nrows=2)
fig.tight_layout(pad=3.2)
 
newdata = newdf.groupby('smoking-number').mean().reset_index()
sem = newdf.groupby('smoking-number').sem().reset_index()

# 将smoking-number转为字符串,标记为分类
newdata['smoking-number'] = newdata['smoking-number'].astype(str)
sem['smoking-number'] = sem['smoking-number'].astype(str)

newdata.plot.line(x='smoking-number', y='distance', yerr=sem, ax=axes[0], legend=False)
newdata.plot.line(x='smoking-number', y='duration', yerr=sem, ax=axes[1], legend=False)

upperbounddistance = max(newdata[['distance']].values) + max(sem[['distance']].values)
lowerbounddistance = min(newdata[['distance']].values) - min(sem[['distance']].values)
upperboundduration = max(newdata[['duration']].values) + max(sem[['duration']].values)
lowerboundduration = min(newdata[['duration']].values) - min(sem[['duration']].values)

axes[0].set_ylim(lowerbounddistance, upperbounddistance)
axes[1].set_ylim(lowerboundduration, upperboundduration)

# 手动设置x轴刻度和标签,确保显示目标值
target_x = ['1.0', '2.0', '3.0']
for ax in axes:
    ax.set_xticks(range(len(target_x)))
    ax.set_xticklabels(target_x)
    ax.set_xlabel("Smoking frequency")

axes[0].set_ylabel("Wayfinding distance")
axes[1].set_ylabel("Wayfinding duration")

plt.show()

补充说明

  • 转换为字符串后,matplotlib会将x轴视为离散分类,自动只显示数据中存在的类别(如果你的数据里没有2.0,代码依然会显示该标签但无对应折线点,可根据实际数据调整target_x列表)
  • 手动设置刻度能确保即使数据中缺失某个分类(比如2.0),x轴依然会显示该标签,符合你的需求

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 03:20:29