2016-11-16 184 views
1

我需要在Plotly中繪製兩個直方圖在一起,其中每個直方圖在平均值處繪製一條線,標籤顯示平均值。我的代碼目前繪製了兩個直方圖,但我不知道如何添加一個平均線與標籤。任何想法?Python Plotly用平均線顯示多條直方圖

import numpy as np 
    import random 
    from plotly.offline import download_plotlyjs, init_notebook_mode, plot, iplot 
    import plotly.graph_objs as go 

    init_notebook_mode() # run at the start of every ipython notebook 

    a = np.random.normal(1500, 100, 1000) 
    b = np.random.normal(1500, 150, 1000) 

    trace1 = go.Histogram(
     x=a, 
     opacity=0.75, 
     histnorm='probability', 
     name='> 180 t/h' 
    ) 
    trace2 = go.Histogram(
     x=b, 
     opacity=0.75, 
     histnorm='probability', 
     name='< 160 t/h', 
     yaxis='y2' 
    ) 

    data = [trace1, trace2] 

    layout = go.Layout(
     title='title', 
     barmode='overlay', 
     xaxis=dict(
     title='' 
     ), 
     yaxis=dict(
      title='Normalized Frequency < 160 t/h' 
     ), 
     yaxis2=dict(
      title='Normalized Frequency > 180 t/h', 
      anchor='free', 
      overlaying='y', 
      side='right', 
      position=1 
     )   
    ) 

    fig = go.Figure(data=data, layout=layout) 
    iplot(fig) 
+1

這會是很好,如果你可以提供數據的樣本來創建一個[MCVE(http://stackoverflow.com/help/mcve) –

+0

我添加了一個隨機正態分佈來生成一些虛擬數據。需要大量數據才能生成合適的直方圖,因此添加原始數據源不可行 – user1035217

+0

您可以使用袖釦嗎? –

回答

2

擺弄後幾個小時,我覺得我得到的東西,大致的工作原理:

a = np.random.normal(1200, 100, 1000) 
b = np.random.normal(1500, 150, 1000) 
df = pd.DataFrame(np.transpose([a,b]), columns=['a','b']) 
a = df.a 
b = df.b 

trace1 = go.Histogram(
    x=df.a, 
    opacity=0.75, 
    histnorm='probability', 
    name='> 180 t/h' 
) 
trace2 = go.Histogram(
    x=df.b, 
    opacity=0.75, 
    histnorm='probability', 
    name='< 160 t/h', 
    yaxis='y2' 
) 

# Create traces 


data = [trace1, trace2] 

layout = go.Layout(
    title='item', 
    barmode='overlay', 
    xaxis=dict(
    title='' 
    ), 
    yaxis=dict(
     title='Normalized Frequency < 160 t/h' 
    ), 
    yaxis2=dict(
     title='Normalized Frequency > 180 t/h', 
     anchor='free', 
     overlaying='y', 
     side='right', 
     position=1 
    ), 

    # Mean lines 
    shapes= [{'line': {'color': '#0099FF', 'dash': 'solid', 'width': 1}, 
    'type': 'line', 
    'x0': df.a.mean(), 
    'x1': df.a.mean(), 
    'xref': 'x', 
    'y0': -0.1, 
    'y1': 1, 
    'yref': 'paper'}, 
    {'line': {'color': '#FDAB5A', 'dash': 'solid', 'width': 1}, 
    'type': 'line', 
    'x0': df.b.mean(), 
    'x1': df.b.mean(), 
    'xref': 'x', 
    'y0': -0.1, 
    'y1': 1, 
    'yref': 'paper'}], 

    # Annotations 
    annotations=[ 
     dict(
      x=df.a.mean(), 
      y=1, 
      xref='x', 
      yref='paper', 
      text="Mean a = {:,.0f}".format(df.a.mean()), 
      showarrow=True, 
      arrowhead=7, 
      ax=1, 
      ay=1, 
      axref='paper', 
      ayref='paper' 
     ), 
     dict(
      x=df.b.mean(), 
      y=0.95, 
      xref='x', 
      yref='paper', 
      text="Mean b = {:,.0f}".format(df.b.mean()), 
      showarrow=True, 
      arrowhead=7, 
      ax=1, 
      ay=1, 
      axref='paper', 
      ayref='paper' 
     ) 
    ] 

) 
fig = go.Figure(data=data, layout=layout) 
py.iplot(fig) 

Result graph


起初我嘗試使用cufflinks去實現它。這工作得很好:

import cufflinks as cf 

df.iplot(kind='histogram', histnorm='probability', barmode='overlay', 
    vline=[dict(x=df.a.mean(),color='#5283AD'), dict(x=df.b.mean(),color='#FDAB5A')]) 

enter image description here

但是,如果你也嘗試添加註釋,它會刪除vlines。

最後我用圖作爲返回plotlines與vlines但沒有佈局。然後我提取形狀位以手動創建上述解決方案。

# Return a dict 
plotdict = df.iplot(kind='histogram', histnorm='probability', barmode='overlay', 
    vline=[dict(x=df.a.mean(),color='#5283AD'), dict(x=df.b.mean(),color='#FDAB5A')], 
    asFigure=True) 

https://plot.ly/~jmarrec/326/

+0

謝謝Julien!你一直很好的幫助 – user1035217