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

创建分段条形图时触发ValueError:数组长度不一致求助

问题分析与解决方案

错误原因

报错ValueError: All arrays must be of the same length是因为data字典中x_values和y_values的长度不匹配:

  • y_values包含6个元组,对应6条条形图的位置与高度
  • 原代码中x_values按5个类别收集数据,最终长度为5,和y_values的6无法匹配

同时原代码逻辑颠倒:应该是每条条形图对应5个类别分段,而非5个类别对应6条条形。

修正后的完整代码

import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.patches import Patch
import tkinter as tk
from tkinter import messagebox

# 定义数据结构:6条条形图,对应y轴的6个Jobs
data = {
    'x_values': [],
    'y_values': [(6.0, 2), (8.5, 2), (12.5, 2), (15.0, 2), (19.0, 2), (21.5, 2)]
}

# 颜色与类别定义
colors = ('tab:red', 'tab:orange', 'tab:purple', 'tab:blue', 'tab:green')
categories = ('Category 1', 'Category 2', 'Category 3', 'Category 4', 'Category 5')
# 6条条形对应的标签
job_labels = ['#3-actual', '#3-budget', '#2-actual', '#2-budget', '#1-actual', '#1-budget']

# 获取用户输入的分段数据
def get_x_values():
    global data
    x_values = []
    try:
        # 遍历6条条形图
        for i in range(len(job_labels)):
            segment_list = []
            # 每条条形对应5个类别分段
            for j in range(len(categories)):
                input_str = x_values_entry[i][j].get().strip()
                if not input_str:
                    raise ValueError(f"第{i+1}条条形的{categories[j]}输入不能为空")
                start, duration = input_str.split(',')
                start = int(start)
                duration = int(duration)
                # 验证时长为正整数
                if duration <=0:
                    raise ValueError(f"{categories[j]}的时长必须是正整数")
                segment_list.append((start, duration))
            # 验证当前条形的分段起始值递增,避免重叠
            sorted_starts = sorted([seg[0] for seg in segment_list])
            if sorted_starts != [seg[0] for seg in segment_list]:
                messagebox.showwarning("输入警告", f"第{i+1}条条形的分段起始值未按递增顺序输入,可能导致重叠")
            x_values.append(segment_list)
        data['x_values'] = x_values
        root.destroy()
    except ValueError as e:
        messagebox.showerror("输入错误", str(e))

# 创建GUI
root = tk.Tk()
root.title("分段条形图数据输入")

# 布置输入网格:6行(对应6条条形),每行5个输入框(对应5个类别)
x_values_entry = []
for i in range(len(job_labels)):
    label = tk.Label(root, text=job_labels[i])
    label.grid(row=i, column=0, padx=5, pady=5)
    entries = []
    for j in range(len(categories)):
        entry = tk.Entry(root, width=12)
        entry.grid(row=i, column=j+1, padx=3, pady=5)
        # 示例提示
        entry.insert(0, "0,1")
        entries.append(entry)
    x_values_entry.append(entries)

# 提交按钮
submit_button = tk.Button(root, text='提交数据', command=get_x_values)
submit_button.grid(row=len(job_labels), columnspan=len(categories)+1, pady=10)

# 运行GUI
root.mainloop()

# 为DataFrame添加颜色数据:每条条形对应5个颜色
data['facecolors'] = [list(colors) for _ in range(len(data['x_values']))]

# 创建DataFrame
df = pd.DataFrame(data)

# 绘制分段条形图
fig, ax = plt.subplots(figsize=(10,6))

for i, row in df.iterrows():
    ax.broken_barh(row['x_values'], row['y_values'], facecolors=row['facecolors'])

# 创建图例
legend_entries = [Patch(facecolor=color, edgecolor='black', label=category) 
                  for color, category in zip(colors, categories)]
ax.legend(handles=legend_entries, loc='upper right', ncol=5, bbox_to_anchor=(1.0, 1.02))

# 自定义坐标轴
ax.set_xlabel('Days')
ax.set_ylabel('Jobs')
ax.set_yticks([7, 9.5, 13.5, 16, 20, 22.5], labels=job_labels)
title = ax.set_title('Tasks and Crew-Days')
title.set_position([0.5, 1.0])
ax.set_ylim(5, 26)
ax.grid(True)

plt.tight_layout()
plt.show()

关键修改说明

  • 数据结构调整:将x_values改为收集6组数据(对应6条条形),每组包含5个分段,确保和y_values长度一致
  • GUI布局优化:按6条条形(Jobs标签)布置输入行,每行对应5个类别分段输入,符合需求逻辑
  • 输入验证增强:添加空值检查、整数格式验证、时长正整数验证,以及分段起始值递增提示,避免数据错误
  • 颜色赋值修正:为每条条形生成对应的5个颜色列表,确保分段颜色与类别一一匹配
  • 用户体验优化:添加输入框示例提示、错误弹窗警告,提升使用友好性

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 20:44:56