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

如何在同一直方图中同时展示频数(frequency)与密度(density)

如何在Matplotlib直方图中同时展示频数和密度(双Y轴)

当然可以实现,核心思路是用双Y轴分别展示频数和密度。下面是修改后的代码,直接满足你的需求:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

x = [6.950915827194559, 0.5704464713012669, -1.655326152372283, 5.867122206816244, -1.809359944941513, -6.164821482653027, -2.538999462076397, 0.2108693568484643, -8.740600769897465, 2.121232876712331, 7.967032967032961, 10.61701196601832, 1.847419201771516, 0.6858006670780847, -2.008695652173909, 2.86991153132885, 1.703131050506168, -1.346913193356314, 3.334927671049193, -15.64688995215311, 20.00022688856367, 10.05956454173731, 2.044936877124148, 3.06513409961684, -0.9973614775725559, 1.190631873030967, -1.509991311902692, -0.3333827233664155, 1.898473282442747, 1.618299899267539, -0.1897860593512823, 1.000000000000001, 3.03501945525293, -7.646697418593529, -0.9769069279216391, -2.918403811792736, -3.90929422276739, 9.609846259653532, 3.240690674452962, 10.08973134408675, 1.98356309650054, 1.915301127899549, -0.7792207792207684, -3.308682400714091, -3.312977099236647, 19.98101265822785, 3.661973444534827, -5.770676691729326, 0.5268044012063156, -1.573767040370533, 3.234974862888484, -1.514352732634994, 6.564849624060143, 9.956794019127146, 3.232590278195024, 2.042007001166857, 1.601164483260553, -2.384737678855331, -2.731242556570068, 0.6069707315088602, 1.40561881957264, -6.805306861851957, 2.492102492102499, -3.639688275501762, 0.7958485384154335, 2.799187725631769, 0.9195966872689088, -2.366608280379856, 0.797679477882518, -3.80380434782609]

df = pd.DataFrame(x, columns=["Returns"])

def plot_histogram():
    bins = range(-11, 12, 1)
    bins_str = [f"{i}%" for i in bins]
    bins_str[-1] = "Over"
    bins_str[0] = "Under"
    
    fig, ax = plt.subplots(figsize=(9, 5))
    
    # 绘制频数直方图,获取区间计数
    counts, bins, patches = ax.hist(np.clip(df.Returns, bins[0], bins[-1]), 
                                    bins=bins, density=False, rwidth=0.8, color='#1f77b4')
    
    # 手动计算密度:密度 = 频数 / (总样本数 × 区间宽度)
    total_samples = len(df.Returns)
    bin_width = bins[1] - bins[0]
    density = counts / (total_samples * bin_width)
    
    # 创建右侧Y轴用于展示密度
    ax2 = ax.twinx()
    # 绘制密度条形图,调整宽度避免和频数图重叠
    ax2.bar(bins[:-1] + bin_width*0.1, density, width=bin_width*0.6, alpha=0.6, color='#ff7f0e')
    
    # 设置X轴样式
    ax.set_xticks(bins)
    ax.set_xticklabels(bins_str)
    ax.set_xlim([bins[0], bins[-1]])
    
    # 设置Y轴标签与样式区分
    ax.set_ylabel('频数', fontsize=12)
    ax2.set_ylabel('密度', fontsize=12, color='#ff7f0e')
    ax2.tick_params(axis='y', labelcolor='#ff7f0e')
    
    # 标题与网格
    ax.set_title("Returns Distribution(频数+密度)", fontsize=14)
    ax.grid(axis="y", linewidth=0.5)
    
    # 添加图例
    ax.legend(['频数'], loc='upper left')
    ax2.legend(['密度'], loc='upper right')
    
    plt.tight_layout()
    plt.show()

plot_histogram()

关键逻辑说明:

  1. 优先获取频数:关闭density=True,用默认的density=False绘制频数直方图,得到每个区间的样本计数
  2. 手动计算密度:根据密度的数学定义,用频数除以「总样本数×区间宽度」得到密度值
  3. 双Y轴分离展示:通过ax.twinx()创建右侧独立Y轴,绘制密度条形图时微调位置避免重叠
  4. 视觉区分:用不同颜色、图例区分频数和密度,让图表可读性更强

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 12:50:20