在PyCharm绘制直方图遇ValueError:bins数组需单调递增求助
解决Matplotlib直方图报错:ValueError: bins must increase monotonically
错误原因
你调用plt.hist(x, y)时,第二个参数y被Matplotlib当作了区间边界(bins参数),但y数组并非严格单调递增(存在2.3→0.0的下降值,还有重复项),违反了bins必须单调递增的要求,因此触发报错。
另外,你的数据是已统计好的区间端点和对应频率,不适合用plt.hist的常规统计用法,更适合用柱状图直接绘制,或者调整参数适配。
解决方案
方案1:用plt.bar绘制频率直方图(推荐)
直接基于已统计的区间和频率绘制,处理掉宽度为0的无效区间(比如你的x中重复的39.5对应的区间):
import matplotlib.pyplot as plt x = [19.5, 23.5, 31.5, 35.5, 39.5, 39.5, 43.5, 47.5] y = [58.1, 23.3, 9.3, 4.7, 2.3, 0.0, 2.3, 0.0] # 过滤宽度为0的无效区间 valid_intervals = [] valid_freq = [] for i in range(len(x)-1): interval_width = x[i+1] - x[i] if interval_width > 0: valid_intervals.append((x[i], x[i+1])) valid_freq.append(y[i]) # 计算区间中点作为柱状图的x轴位置,用区间宽度作为柱子宽度 mid_points = [(left + right)/2 for left, right in valid_intervals] bar_widths = [right - left for left, right in valid_intervals] plt.bar(mid_points, valid_freq, width=bar_widths, edgecolor='black') plt.xlabel('区间') plt.ylabel('频率') plt.title('频率直方图') plt.show()
方案2:用plt.hist(需生成原始样本)
如果一定要用plt.hist,需要将频率数据还原为近似的原始样本,再指定合法的bins:
import matplotlib.pyplot as plt import numpy as np x = [19.5, 23.5, 31.5, 35.5, 39.5, 39.5, 43.5, 47.5] y = [58.1, 23.3, 9.3, 4.7, 2.3, 0.0, 2.3, 0.0] # 生成近似原始样本(将频率放大10倍取整,避免小数频数) raw_data = [] for i in range(len(x)-1): sample_count = int(y[i] * 10) # 在对应区间内生成随机样本 raw_data.extend(np.random.uniform(x[i], x[i+1], sample_count)) # 用去重并排序后的x作为合法的bins plt.hist(raw_data, bins=sorted(set(x)), edgecolor='black') plt.xlabel('数值') plt.ylabel('频数') plt.title('直方图') plt.show()
内容的提问来源于stack exchange,提问作者Herman Mokgope
相关产品推荐
相关产品推荐

