Plotly: Как построить кумулятивную гистограмму "шагов"?
Я пытаюсь построить кумулятивную гистограмму, используя Plotly в python, но сделать так, чтобы она выглядела как "шаги", то есть столбцы без цвета и отображается только верхняя линия. Что-то вроде этого:
По сути, я пытаюсь воспроизвести поведение следующего кода 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])
Так в чем же подвох?
1 ответ
Если вы хотите обработать процесс накопления и накопления данных до того, как подготовите данные, вы можете использовать go.Scatter
объект со свойством shape линии, установленной в 'hvh'
,
Участок:
Код: Настройка для ноутбука Jupyter
#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 debugginh
#%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, сигма = 5 и 500 наблюдений. x
затем положить в 50 бункеров, используя np.histogram()
который возвращает два массива. Они используются в качестве источника данных для графика.
Возможные альтернативные подходы:
Я также попытался использовать ваш фрагмент с некоторыми случайными образцами данных и включить shape='hvh'
в вашем line=dict(color="red", width=1)
, Это не похоже на работу, хотя. Я также рассмотрел изменение макета вашего go.Histogram()
так что была построена только верхняя линия столбцов, но я не думаю, что это возможно.
Принятое решение работает, но может иметь ограничения, поскольку все ячейки имеют одинаковую ширину. Один из подходов - использовать 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)