【问题标题】:Python: How to stack or overlay histograms using PlotlyPython:如何使用 Plotly 堆叠或覆盖直方图
【发布时间】:2021-02-27 04:36:21
【问题描述】:

我在不同的列表中有两组数据。每个列表元素都有一个从 0:100 开始的值,并且元素重复。

例如:
first_data = [10,20,40,100,...,100,10,50]
second_data = [20,50,50,10,...,70,10,100]

我可以使用以下方法在直方图中绘制其中一个:

import plotly.graph_objects as go
.
.
.

fig = go.Figure()
fig.add_trace(go.Histogram(histfunc='count', x=first_data))
fig.show()

通过将histfunc 设置为'count',我的直方图由从0 到100 的x 轴和first_data 中重复元素数量的条形图组成。

我的问题是:如何使用相同的“计数”直方图在同一轴上叠加第二组数据?

【问题讨论】:

    标签: python python-3.x graph plotly histogram


    【解决方案1】:

    执行此操作的一种方法是简单地添加另一个跟踪,您就快到了!用于创建这些示例的数据集可以在本文的最后一部分中找到。

    注意:
    下面的代码使用了'lower-level' plotly API,因为(个人)我觉得它更透明,并且使用户能够看到正在绘制的内容以及原因;而不是依赖graph_objectsexpress 的便利模块。

    选项 1 - 重叠条:

    from plotly.offline import plot
    
    layout = {}
    traces = []
    
    traces.append({'x': data1, 'name': 'D1', 'opacity': 1.0})
    traces.append({'x': data2, 'name': 'D2', 'opacity': 0.5})
    
    # For each trace, add elements which are common to both.
    for t in traces:
        t.update({'type': 'histogram',
                  'histfunc': 'count',
                  'nbinsx': 50})
    
    layout['barmode'] = 'overlay'
    
    plot({'data': traces, 'layout': layout})
    

    输出 1:

    选项 2 - 曲线图:

    另一种选择是绘制分布曲线(高斯 KDE),如下所示。值得注意的是,此方法绘制的是概率密度,而不是计数。

    X1, Y1 = calc_curve(data1)
    X2, Y2 = calc_curve(data2)
    
    traces = []
    traces.append({'x': X1, 'y': Y1, 'name': 'D1'})
    traces.append({'x': X2, 'y': Y2, 'name': 'D2'})
    
    plot({'data': traces})
    

    输出 2:

    关联calc_curve()函数:

    from scipy.stats import gaussian_kde
    
    def calc_curve(data):
        """Calculate probability density."""
        min_, max_ = data.min(), data.max()
        X = [min_ + i * ((max_ - min_) / 500) for i in range(501)]
        Y = gaussian_kde(data).evaluate(X)
        return(X, Y)
    

    选项 3 - 绘制条形图和曲线:

    或者,您可以随时将这两种方法结合在一起,使用 y 轴上的概率密度。

    layout = {}
    traces = []
    
    traces.append({'x': data1, 'name': 'D1', 'opacity': 1.0})
    traces.append({'x': data2, 'name': 'D2', 'opacity': 0.5})
    
    for t in traces:
        t.update({'type': 'histogram',
                  'histnorm': 'probability density',
                  'nbinsx': 50})
    
    traces.append({'x': X1, 'y': Y1, 'name': 'D1'})
    traces.append({'x': X2, 'y': Y2, 'name': 'D2'})
    
    layout['barmode'] = 'overlay'
    
    plot({'data': traces, 'layout': layout})  
    

    输出 3:

    数据集:

    这是用于模拟 [0,100] 值的数据集并创建这些示例的代码:

    import numpy as np
    from sklearn.preprocessing import MinMaxScaler
    
    mms = MinMaxScaler((0, 100))
    np.random.seed(4)
    data1 = mms.fit_transform(np.random.randn(10000).reshape(-1, 1)).ravel()
    data2 = mms.fit_transform(np.random.randn(10000).reshape(-1, 1)).ravel()
    

    【讨论】:

    • 非常感谢!
    • 很高兴,希望对您有所帮助。这是一个有趣的问题,感谢您的大脑锻炼。
    • 我确实有关于您的 calc_curve 方法的后续问题。我将代码中的 data1 和 data2 分别替换为我的数据变量,第一次编译导致错误:列表对象没有属性 .min() 和 .max()。因此,我尝试将我的数据变量转换为 np.array(data) 并再次尝试。这次它在抱怨:TypeError:'int' 和'NoneType' 的实例之间不支持'
    • 似乎使用的最小/最大值之一是None;虽然我不明白这是怎么回事。我建议使用完全可重现的代码发布一个新问题(请),并在对该问题的评论中标记我。我明天去找你。
    • 别担心,伙计,一切顺利。保持安全。
    猜你喜欢
    • 2020-01-19
    • 2015-11-28
    • 1970-01-01
    • 1970-01-01
    • 2014-03-12
    • 1970-01-01
    • 2017-02-05
    • 2014-03-12
    • 2016-12-19
    相关资源
    最近更新 更多