簡體   English   中英

Plotly 中的條件格式

[英]Conditional formatting in Plotly

這個問題是關於如何在 Plotly 中進行條件格式的。

可能需要這樣做的實例:

  • 散點圖,其中點需要着色(即彩虹)作為 2 個變量的函數;
  • 交互式圖表,其中着色取決於參數值;
  • 直方圖,其中的部分需要不同的顏色。

在這里,我將專門詢問直方圖。

取以下數據:

data = np.random.normal(size=1000)

我想要一個直方圖,其中高於 0 的值在不同的顏色下分箱。

一個簡單的解決方案是

hist1 = go.Histogram(x=data[data<0], 
                    opacity=0.75, 
                    histnorm='density',
                    showlegend=False,
                    )
hist2 = go.Histogram(x=data[data>=0], 
                    opacity=0.75, 
                    histnorm='density',
                    showlegend=False,
                    )
layout = go.Layout(barmode='overlay')
fig = go.Figure(data=[hist1, hist2], layout=layout)
iplot(fig, show_link=False)

在此處輸入圖片說明

這個解決方案有幾個問題:

  1. 2 個直方圖的默認 bin 大小不同,導致在零附近重疊。
  2. 如果我想要histnorm = 'probability density'結果圖“標准化”每個單獨的直方圖,所以它們看起來不成比例。
  3. 兩個直方圖的分箱從左側開始,因此最后一個分箱可能會超出零以下值的直方圖。

有一個更好的方法嗎?


更新

好的,我可以使用xbins解決(1)和(3):

hist1 = go.Histogram(x=data[data>=0], 
                    opacity=0.75, 
                    xbins=dict(
                        start=0,
                        end=4,
                        size=0.12),
                    histnorm='density',
                    showlegend=False,
                    )
hist2 = go.Histogram(x=data[data<0], 
                    opacity=0.75, 
                    xbins=dict(
                        start=-0.12*33,
                        end=0,
                        size=0.12),
                    histnorm='density',
                    showlegend=False,
                    )
layout = go.Layout(barmode='overlay')
fig = go.Figure(data=[hist1, hist2], layout=layout)
iplot(fig, show_link=False)

在此處輸入圖片說明

但是,我如何解決第二個問題?

為了...

如果我想要 histnorm = 'probability density' 結果圖“標准化”每個單獨的直方圖,所以它們看起來不成比例。

...部分似乎您必須先對整個樣本進行標准化,然后再將其拆分為兩個不同的直方圖。 這意味着您應該做的是在單個跟蹤下制作具有多種顏色面積圖 但不幸的是,建議的解決方案似乎是為兩條軌跡分配不同的顏色......

df_pos = df.where(df < 0, 0)
df_neg = df.where(df > 0, 0)

......這當然會讓你回到你所在的地方。

所以為了得到你想要的東西,看來你得把自己從gi.Histogram的界限中gi.Histogram出來, gi.Histogram binning 和 normalization 搞清楚,然后再結合使用面積圖或條形圖。 據我了解,這將處理所有三個要點。 以下是有關如何做到這一點的建議:

陰謀:

在此處輸入圖片說明

代碼:

# imports
import plotly.graph_objects as go
from plotly.offline import iplot
import pandas as pd
import numpy as np

# theme
import plotly.io as pio
#pio.templates
#pio.templates.default = "plotly_white"
pio.templates.default = "none"

# Some sample data
np.random.seed(123)
x = np.random.normal(0, 1, 1000)

# numpy binning
binned = np.histogram(x, bins=30, density=True)

# retain some info abou the binning
yvals=binned[0]
x_last = binned[1][-1]
xvals=binned[1][:-1]

# organize binned data in a pandas dataframe
df_bin=pd.DataFrame(dict(x=xvals, y=yvals))
df_bin_neg = df.where(df['x'] < 0)
df_bin_pos = df.where(df['x'] > 0)

# set up plotly figure
fig=go.Figure()

# neagtive x
fig.add_trace(go.Scatter(
    x=df_bin_neg['x'],
    y=df_bin_neg['y'],
    name="negative X",
    hoverinfo='all',
    fill='tozerox',
    #fillcolor='#ff7f0e',
    fillcolor='rgba(255, 103, 0, 0.7)',

    line=dict(color = 'rgba(0, 0, 0, 0)', shape='hvh')
))

# positive x
fig.add_trace(go.Scatter(
    x=df_bin_pos['x'],
    y=df_bin_pos['y'],
    name="positive X",
    hoverinfo='all',
    fill='tozerox',
    #opacity=0.2,
    #fillcolor='#ff7f0e',
    #fillcolor='#1f77b4',
    fillcolor='rgba(131, 149, 193, 0.9)',
    line=dict(color = 'rgba(0, 0, 0, 0)', shape='hvh')
))

# adjust layout to insure max values are included
ymax = np.max([df_bin_neg['y'].max(), df_bin_neg['y'].max()])
fig.update_layout(yaxis=dict(range=[0,ymax+0.1]))

# adjust layout to match OPs original
fig.update_xaxes(showline=True, linewidth=1, linecolor='black', mirror=False, zeroline=False, showgrid=False)
fig.update_yaxes(showline=False)#, linewidth=2, linecolor='black', mirror=True)

fig.show()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM