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

Matplotlib非数值柱状图绘制问题咨询:报错与绘图异常

让我逐个帮你解决这两个Matplotlib绘图的问题:

问题1:解决"Empty 'DataFrame': no numeric data to plot"报错并绘制非堆叠柱状图

这个报错的核心原因很直观:你的DataFrame里存储的都是A/B/C/D这类字符串等级,而Matplotlib的绘图函数需要数值型数据才能生成柱状图。我们需要先把等级转换成可量化的数值,再进行绘图。

这里提供一个直接可行的解决方案,步骤如下:

  1. 创建一个等级到数值的映射字典(比如按GPA标准,A=4、B=3、C=2、D=1,你可以根据需求调整);
  2. 将DataFrame中的字符串等级批量转换为数值;
  3. 使用Pandas内置的plot()方法直接绘制非堆叠柱状图。

完整代码示例:

import pandas as pd
import matplotlib.pyplot as plt

# 初始化你的DataFrame
df = pd.DataFrame(
    {'midterm':['A','B','B','D'],'Final':['C','A','D','B']},
    index=['math', 'sport', 'History', 'Physics']
)

# 定义等级与数值的映射关系
grade_to_num = {'A':4, 'B':3, 'C':2, 'D':1}
# 转换所有列的字符串为数值
df_numeric = df.applymap(lambda x: grade_to_num[x])

# 绘制非堆叠柱状图
df_numeric.plot(kind='bar', stacked=False, figsize=(8, 5))
plt.title('Midterm vs Final Course Grades')
plt.ylabel('Grade Value')
plt.xticks(rotation=0)  # 让科目名称水平显示,提升可读性
plt.show()

这样处理后,每门科目会显示两根独立的柱子,分别对应期中、期末的成绩数值,完美解决无数值数据的报错问题。


问题2:修复手动绘图的两个缺陷(等级顺序乱、Y轴遮挡柱子)

你的手动绘图代码存在两个关键问题:

  1. 直接使用字符串等级作为柱状图高度,Matplotlib会默认按字符串的ASCII码排序,而非你需要的A→B→C→D逻辑顺序;
  2. plt.xticks=(index,xticks)是错误的赋值写法,而非调用函数,且Y轴默认从0开始,导致低等级的柱子被遮挡。

下面是修正后的完整代码,同时解决两个问题:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

df = pd.DataFrame(
    {'midterm':['A','B','B'],'Final':['C','A','D']},
    index=['math', 'sport', 'History']
)

# 第一步:将等级转换为数值,统一逻辑顺序
grade_to_num = {'A':4, 'B':3, 'C':2, 'D':1}
df_numeric = df.applymap(lambda x: grade_to_num[x])

fig, ax = plt.subplots(figsize=(8, 5))
index = np.asarray([0, 1])  # 调整X轴索引为连续整数,避免间距过大
width = 0.25  # 缩小柱子宽度,防止重叠

# 绘制三门课的期中/期末成绩柱子
plt.bar(index, df_numeric.iloc[0,:], width, label='Math')
plt.bar(index + width, df_numeric.iloc[1,:], width, label='Sport')
plt.bar(index + 2*width, df_numeric.iloc[2,:], width, label='History')

# 修正X轴刻度:放在每组柱子的中间位置,正确调用xticks函数
xticks_labels = ['midterm', 'final']
plt.xticks(index + width, xticks_labels)

# 自定义Y轴:强制按D→C→B→A的逻辑顺序显示刻度
ax.set_yticks([1, 2, 3, 4])
ax.set_yticklabels(['D', 'C', 'B', 'A'])

# 调整Y轴范围,避免最矮的柱子被底部遮挡
plt.ylim(0.8, 4.2)

plt.legend()
plt.title('Course Grades: Midterm vs Final')
plt.show()

关键修正点说明:

  • 通过数值映射,既解决了字符串无法作为高度的问题,又能通过自定义Y轴标签强制等级顺序;
  • 修正了plt.xticks的调用方式,将刻度放在三组柱子的中间,视觉上更协调;
  • 调整Y轴下限到0.8,确保所有等级对应的柱子都能完整显示。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 06:30:21