
本文详解在 pandas + matplotlib 环境下绘制分组箱线图的常见错误与正确实践,重点解决因数据维度不匹配导致的 `valueerror: x must have 2 or fewer dimensions` 错误,并提供可直接运行的完整示例代码。
在使用 matplotlib.pyplot.boxplot() 绘制分组箱线图时,一个高频陷阱是:误将整个 DataFrame(二维结构)直接传入 boxplot(),而该函数要求每个待绘图的数据项必须是 一维数组(如 Series、list 或 ndarray)。当你执行 ran_data = [ry, rn] 且 ry、rn 仍是完整的 DataFrame 时,boxplot() 会尝试对二维对象进行统计计算,从而抛出 ValueError: X must have 2 or fewer dimensions —— 实际上它拒绝接受超过一维的输入。
✅ 正确做法是:显式提取目标数值列(例如 "Pulse"),生成两个一维 pandas.Series 对象,再构造成列表传入。以下是修正后的完整流程:
import matplotlib.pyplot as plt
import pandas as pd
# 读取数据
pulserate = pd.read_csv("PulseNew.csv")
# 按条件筛选子集(返回 DataFrame)
ran_yes = pulserate[pulserate["Ran"] == "yes"]
ran_no = pulserate[pulserate["Ran"] == "no"]
# ✅ 关键步骤:提取数值列(Series),而非保留整个 DataFrame
ry_pulse = ran_yes["Pulse"] # 类型:pandas.Series(1D)
rn_pulse = ran_no["Pulse"] # 类型:pandas.Series(1D)
# 构造用于 boxplot 的数据列表(每个元素为 1D 可迭代对象)
ran_data = [ry_pulse, rn_pulse]
# 绘图
plt.boxplot(ran_data, labels=["Ran: Yes", "Ran: No"]) # 添加标签提升可读性
plt.ylabel("Pulse Rate")
plt.title("Pulse Rate Distribution by Running Habit")
plt.grid(True, alpha=0.3)
plt.show()⚠️ 注意事项:
- ❌ 错误写法 subset = pulserate[(pulserate["Ran"] == "yes") & (pulserate["Ran"] == "no")] 逻辑恒为假(同一行不可能同时满足 "yes" 和 "no"),结果为空 DataFrame,故绘图为空白;
- ✅ 推荐使用 pandas.DataFrame.boxplot() 作为替代方案,语法更简洁且自动处理分组:
pulserate.boxplot(column="Pulse", by="Ran") plt.suptitle("") # 移除默认的总标题 plt.show() - 若原始 CSV 中 "Pulse" 列含缺失值(NaN),boxplot() 会自动忽略,但建议提前检查:print(pulserate["Pulse"].isna().sum());
- 确保 "Ran" 列值严格为字符串 "yes"/"no"(注意大小写与空格),否则筛选将无结果;可用 pulserate["Ran"].unique() 快速验证。
掌握“筛选 → 提取列 → 构造一维序列列表”这一标准链路,即可稳健构建任意多组箱线图,为后续探索性数据分析(EDA)打下坚实基础。










