2

我试图在 python 中使用 Plotly 绘制累积直方图,但让它看起来像“步骤”,即没有颜色的条形图,只显示顶线。像这样的东西:

在此处输入图像描述

基本上,我试图重现以下 matplotlib 代码的行为:

import matplotlib.pyplot as plt
plt.hist(x, cumulative=True, histtype='step')

到目前为止,我能做的最好的是:

import plotly.graph_objs as go
from plotly.offline import iplot
h = go.Histogram(x=x,
                         cumulative=dict(enabled=True),
                         marker=dict(color="rgba(0,0,0,0)",
                                     line=dict(color="red", width=1)))
iplot([h])

结果如下:
在此处输入图像描述

那么诀窍是什么?

4

2 回答 2

4

如果您愿意在绘制数据之前go.Scatter处理分箱和累积,则可以使用将线的 shape 属性设置为 的对象'hvh'

阴谋:

在此处输入图像描述

代码: Jupyter Notebook 的设置

#imports
import plotly.plotly as py
import plotly.graph_objs as go
from plotly.offline import download_plotlyjs, init_notebook_mode, plot, iplot

import numpy as np
import pandas as pd

# qtconsole for debugging
#%qtconsole -- style vim

# Notebook settings
init_notebook_mode(connected=True)

# Some sample data
x = np.random.normal(50, 5, 500)
binned = np.histogram(x, bins=25, density=True)
plot_y = np.cumsum(binned[0])

# Line
trace1 = go.Scatter(
    x=binned[1],
    y=plot_y,
    mode='lines',
    name="X",
    hoverinfo='all',
    line=dict(color = 'rgb(1255, 0, 0)', shape='hvh'
    )
)

data = [trace1]

# Layout
layout = dict(title = 'Binned data from normal distribution',
    legend=dict(
        y=0.5,
        traceorder='reversed',
        font=dict(
            size=16
        )
    )
)

# Make figure
fig = dict(data=data, layout=layout)

# Plot
iplot(fig, filename='line-shapes')

我希望这是你可以使用的东西!

如果没有,请随时告诉我。

一些细节:

数据样本是使用np.random.normal(). x是平均值 = 50、sigma = 5 和 500 个观测值的采样正态分布。x然后放入 50 个 bin 中,使用np.histogram()它返回两个数组。这些用作绘图的数据源。

可能的替代方法:

我还尝试将您的代码段与一些随机样本数据一起使用,并包含shape='hvh'在您的line=dict(color="red", width=1). 但这似乎不起作用。我还考虑过修改您的布局,go.Histogram()以便只绘制条形的顶线,但我认为这是不可能的。

于 2019-03-19T09:26:30.687 回答
3

可接受的解决方案有效,但可能会受到限制,因为这些箱的宽度都相同。一种方法是使用 matplotlib 计算统计数据,然后用 plotly 绘制:

# sample data
# I am not using a normal distribution on purpose so that the effect of varying bin widths is apparent.
x = np.random.rand(100)

# use matplotlib to get "n" and "bins"
# n_bins will affect the resolution of the cumilative histogram but not dictate the bin widths.
n_bins = 100
n, bins, patches = plt.hist(x, n_bins, density=True, histtype='step', cumulative=-1)

# use plotly (v3) to plot
data = []
trace = go.Scatter(
    x=bins,
    y=n,
    mode='lines',
    name= "test",
    line=dict(
        shape='hvh'
    )
)

data.append(trace)
fig = go.Figure(data=data)
iplot(fig)

结果应如下所示: 在此处输入图像描述

于 2020-06-17T20:52:10.480 回答