Matplotlib非数值柱状图绘制问题咨询:报错与绘图异常
让我逐个帮你解决这两个Matplotlib绘图的问题:
问题1:解决"Empty 'DataFrame': no numeric data to plot"报错并绘制非堆叠柱状图
这个报错的核心原因很直观:你的DataFrame里存储的都是A/B/C/D这类字符串等级,而Matplotlib的绘图函数需要数值型数据才能生成柱状图。我们需要先把等级转换成可量化的数值,再进行绘图。
这里提供一个直接可行的解决方案,步骤如下:
- 创建一个等级到数值的映射字典(比如按GPA标准,A=4、B=3、C=2、D=1,你可以根据需求调整);
- 将DataFrame中的字符串等级批量转换为数值;
- 使用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轴遮挡柱子)
你的手动绘图代码存在两个关键问题:
- 直接使用字符串等级作为柱状图高度,Matplotlib会默认按字符串的ASCII码排序,而非你需要的
A→B→C→D逻辑顺序; 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
相关产品推荐
相关产品推荐

