【问题标题】:Vertical "broken" bar plot with arrays as bar heights and color coding以数组作为条形高度和颜色编码的垂直“破碎”条形图
【发布时间】:2020-12-30 17:45:06
【问题描述】:

我正在尝试创建一个如下所示的条形图:

x 轴是同时命中的检测器数量(即多重性) 对于每个多重性,我有几个事件。 y 轴包含每个事件的平均脉冲高度。颜色应对应于具有所示脉冲高度并出现在具有相应多重性的事件中的命中数

我有一个字典,它有多重性作为键和平均脉冲高度的数组作为值。 :

averages = {2 : [...],
        3 : [...],
        4 : [...],
        5 : [...],
        6 : [...],}

for key in averages:
plt.bar(key,averages[key] ,width = 0.8)

我只知道如何制作简单版的条形图,如下所示:

有人能告诉我如何让条“断开以显示所有脉冲高度并添加颜色编码吗?

【问题讨论】:

    标签: python matplotlib bar-chart histogram color-coding


    【解决方案1】:

    不完全清楚,但我认为你想要这样的东西

    import seaborn as sns
    from scipy import stats
    import matplotlib as mpl
    import matplotlib.pyplot as plt
    
    # Create some fake data that looks roughly like what you have
    tips = sns.load_dataset("tips")
    weights = stats.gaussian_kde(tips["total_bill"])(tips["total_bill"])
    tips = tips.sample(frac=50, weights=weights, replace=True)
    
    days = []
    segments = []
    counts = []
    for day, x in tips["total_bill"].groupby(tips["day"]):
        days.append(day)
        segments.append(np.sort(x.unique()))
        counts.append(x.value_counts().sort_index())
    
    # Map from counts to colors
    norm = mpl.colors.Normalize(0, np.concatenate(counts).max())
    colors = [mpl.cm.viridis(norm(c)) for c in counts]
    
    f, ax = plt.subplots()
    
    # Draw each horizontal line
    events = ax.eventplot(segments, colors=colors, orientation="vertical", zorder=.5)
    events[0].set_norm(norm)
    f.colorbar(events[0])
    
    # Add the mean/std for each x position
    sns.pointplot(data=tips, x="day", y="total_bill", ci="sd", order=days, join=False, color=".1")
    


    我的问题是需要每条水平线来表示每个数据值,但如果您对直方图感到满意,这是 seaborn 中的两个函数调用 (>=0.11)

    sns.histplot(
        data=tips, x="day", y="total_bill",
        discrete=(True, False), binwidth=(1, .5),
        cmap="viridis", cbar=True, zorder=.5, alpha=.75,
    )
    
    sns.pointplot(
        data=tips, x="day", y="total_bill",
        ci="sd", order=days, join=False, color=".1",
    )
    

    【讨论】:

    • 不知道eventplot。必须检查一下。 +1
    【解决方案2】:

    这是一个使用imshow 生成列式“颜色直方图”的解决方案:

    import matplotlib as mpl
    import matplotlib.pyplot as plt
    import numpy as np
    
    # Create dummy data
    coincidences = [2, 3, 4, 5, 6]
    n_list = [10000, 8000, 6000, 4000, 2000]
    mu_list = np.array([200, 300, 400, 500, 600])
    scale = 100
    averages = {c: np.random.normal(loc=mu_list[i], scale=scale, size=n_list[i])
                for i, c in enumerate(coincidences)}
    
    # Calculate histogram for each column
    bins = np.linspace(0, 1000, 1000)
    hist_img = np.array([np.histogram(averages[c], bins=bins)[0]
                         for c in coincidences]).T
    
    # Create Normalized colormap
    # norm = mpl.colors.Normalize()
    norm = mpl.colors.LogNorm(vmin=1, vmax=hist_img.max())
    sm = mpl.cm.ScalarMappable(cmap='viridis', norm=norm)
    
    # Use colormap for img_hist and make zeros transparent
    hist_img2 = sm.to_rgba(hist_img, bytes=True)
    hist_img2[hist_img == 0, 3] = 0
    
    # Plot
    fig, ax = plt.subplots()
    cc = ax.imshow(hist_img2, aspect='auto', interpolation='none', origin='lower',
                   extent=[1.5, 6.5, 0, 1000])
    plt.colorbar(sm)
    
    mean = [np.mean(averages[c]) for c in coincidences]
    std = [np.std(averages[c]) for c in coincidences]
    ax.errorbar(coincidences, mean, yerr=std, ls='', c='k', capsize=3, label='std')
    ax.plot(coincidences, mean, ls='', marker='o', c='b', label='mean')
    ax.legend()
    

    【讨论】:

    • 这真的很有帮助。非常感谢!
    猜你喜欢
    • 1970-01-01
    • 2013-02-11
    • 1970-01-01
    • 2011-01-23
    • 2014-12-17
    • 2020-03-22
    • 1970-01-01
    • 2023-04-06
    • 1970-01-01
    相关资源
    最近更新 更多