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

如何用点而非条形绘制频率图?已有分箱与频率值

分箱频率点图绘制方案

需求说明

需要绘制分箱频率点图,已提前计算好分箱区间(low_bin、high_bin)和对应频率(frequency),样本数据如下:

import pandas as pd

df_fd = pd.DataFrame({
    'low_bin': [13.142857, 18.857143, 24.571429, 30.285714, 36.000000, 41.714286, 47.428571, 53.142857],
    'high_bin': [18.857143, 24.571429, 30.285714, 36.000000, 41.714286, 47.428571, 53.142857, 58.857143],
    'frequency': [3,5,8,8,7,7,1,1]
})

原代码问题分析

原代码中Y[Y>df_fd['frequency']] = np.nan执行失败,核心原因是维度不匹配:

  • df_fd['frequency']是长度为8的一维数组
  • Y是np.meshgrid生成的二维数组,行数等于最大频率值,列数等于每个分箱的x点数
  • 直接进行比较会触发numpy广播错误,无法逐行匹配分箱的频率阈值

解决方案一:直接生成点坐标(推荐)

跳过meshgrid,直接为每个分箱生成对应数量的点,逻辑更直观:

import matplotlib.pyplot as plt
import numpy as np

fig, ax = plt.subplots(figsize=(8, 5))

# 绘制底层柱状图
ax.bar(
    df_fd.low_bin, 
    df_fd.frequency, 
    width=df_fd.high_bin - df_fd.low_bin,
    edgecolor='black',
    alpha=0.3,
    label='Frequency Bar'
)

# 为每个分箱生成区间内的x坐标(均匀分布,可调整点数)
x_per_bin = np.linspace(df_fd.low_bin, df_fd.high_bin, num=8, axis=1)

# 生成每个分箱对应的y坐标(1到对应frequency的整数)
x_points = []
y_points = []
for idx, freq in enumerate(df_fd.frequency):
    # 取对应分箱的前freq个x点(保证点数和频率一致)
    selected_x = x_per_bin[idx][:freq]
    # 生成y值:1到freq
    selected_y = np.arange(1, freq + 1)
    # 添加到总列表
    x_points.extend(selected_x)
    y_points.extend(selected_y)

# 绘制散点图
ax.scatter(x_points, y_points, color='black', s=20, label='Frequency Points')

# 美化图表
ax.set_xlabel('Value Range')
ax.set_ylabel('Frequency')
ax.legend()
plt.tight_layout()
plt.show()

解决方案二:修正原代码的维度问题

如果坚持使用meshgrid,需要将频率数组转为二维,实现逐行阈值判断:

import matplotlib.pyplot as plt
import numpy as np

fig, ax = plt.subplots(figsize=(8, 5))

# 绘制柱状图
ax.bar(df_fd.low_bin, df_fd.frequency, width=df_fd.high_bin - df_fd.low_bin, edgecolor='black', alpha=0.3)

# 每个分箱生成10个x点
x_per_bin = np.linspace(df_fd.low_bin, df_fd.high_bin, num=10, axis=1)
# 最大频率作为y轴的行数
max_freq = df_fd.frequency.max()
# 生成网格
X, Y = np.meshgrid(x_per_bin[0], np.arange(1, max_freq + 1))

# 将频率转为二维数组(行数与Y一致,列数为1)
freq_2d = df_fd.frequency.values[:, None]
# 创建掩码:Y超过对应分箱频率的位置设为True
mask = Y > freq_2d
# 掩码应用到Y,超过的设为nan
Y[mask] = np.nan

# 扁平化数组并过滤nan
valid_x = X[~np.isnan(Y)]
valid_y = Y[~np.isnan(Y)]

# 绘制散点图
ax.scatter(valid_x, valid_y, color='black', s=20)

ax.set_xlabel('Value Range')
ax.set_ylabel('Frequency')
plt.tight_layout()
plt.show()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 01:13:20