【问题标题】:Plotly: bar plot with color red<0, green>0, divided by groupsPlotly:条形图,颜色为红色<0,绿色>0,按组划分
【发布时间】:2023-01-25 21:50:19
【问题描述】:

给定一个包含 2 个组的数据框:(group1, group2),其值 > 和 < 小于 0: 阴谋:

  • 条形图
  • x = x
  • y = 值,除以组 1、组 2
  • 颜色 = 红色如果值<0,绿色如果值>0
  • 图例以不同颜色显示组 1、组 2。

然而,我当前的代码并没有像我预期的那样着色,并且图例以相同的颜色显示:

import pandas as pd
import numpy as np
import plotly.express as px 

df = pd.DataFrame( {
    "x" : [1,2,3],
    "group1" : [np.nan, 1, -0.5],
    "group2" : [np.nan, -0.2, 1],  
}).set_index("x")


df_ = df.reset_index().melt(id_vars = 'x')
fig = px.bar(df_, x='x', y='value', color='variable', barmode='group')
fig.update_traces(marker_color=['red' if val < 0 else 'green' for val in df_['value']], marker_line_color='black', marker_line_width=1.5)
fig.show()

OUT 表明我想要实现的目标:

【问题讨论】:

  • 抱歉,我编辑的 plotly.express
  • 如果您选择根据 x 值单独对颜色条进行着色,那么图例颜色就没有任何意义吗?

标签: python pandas plotly


【解决方案1】:

由于express无法实现这一点,因此我们使用图形对象为每个组绘制条形图。 Group 1 和Group 2 更改了由数值确定颜色的逻辑,更改了Group 1 和Group 2 的条件。原因是如果不这样做,图例将不会进行颜色编码。

import pandas as pd
import numpy as np
import plotly.express as px 
import plotly.graph_objects as go

df = pd.DataFrame( {
    "x" : [1,2,3],
    "group1" : [np.nan, 1, -0.5],
    "group2" : [np.nan, -0.2, 1],  
}).set_index("x")

df_ = df.reset_index().melt(id_vars = 'x')

fig = go.Figure()

fig.add_trace(go.Bar(x=df_.query('variable =="group1"')['x'],
                     y=df_.query('variable =="group1"')['value'],
                     marker_color=['red' if val < 0 else 'green' for val in df_.query('variable =="group1"')['value']],
                     marker_line_color='black',
                     marker_line_width=1.5,
                     name='group1',
                     #legendgroup='group1'
                    )
             )

fig.add_trace(go.Bar(x=df_.query('variable =="group2"')['x'],
                     y=df_.query('variable =="group2"')['value'],
                     marker_color=['green' if val > 0 else 'red' for val in df_.query('variable =="group2"')['value']],
                     marker_line_color='black',
                     marker_line_width=1.5,
                     name='group2',
                     #legendgroup='group2'
                    )
             )
fig.update_layout(barmode='group', xaxis=dict(title_text='x'), yaxis=dict(title_text='value'))
fig.show()

【讨论】:

    【解决方案2】:

    为了坚持使用plotly.express,我会在您的数据框中添加一列,例如df_['positive'] 用一个布尔值,然后用这个变量给你的图上色。

    它看起来像这样:

    import pandas as pd
    import numpy as np
    import plotly.express as px 
    
    df = pd.DataFrame( {
        "x" : [1,2,3],
        "group1" : [np.nan, 1, -0.5],
        "group2" : [np.nan, -0.2, 1],  
    }).set_index("x")
    
    df_ = df.reset_index().melt(id_vars = 'x')
    df_['positive'] = (df_['value']>=0)
    
    fig = px.bar(df_, x='x', y='value',barmode = 'group',
                    color='positive',
                    color_discrete_map={
                        True: 'green',
                        False: 'red'
                        }
    )
    fig.update_traces(marker_line_color='black', marker_line_width=1.5)
    fig.show('browser')
    

    产生以下结果:

    【讨论】:

      【解决方案3】:

      如果您想根据 x 值(而不是 variable 组)对条形图进行着色,则必须单独更新轨迹(或者您必须手动绘制图形对象):

      fig = px.bar(df_, x='x', y='value', color='variable', barmode='group')
      fig.for_each_trace(
          lambda trace: trace.update(marker_color=np.where(df_.loc[df_['variable'].eq(trace.name), 'value'] < 0, 'red', 'green'))
      )
      fig.update_layout(showlegend=False)  # Hide legend because there is no distinct group
      fig.show()
      

      输出:

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-10-31
        • 1970-01-01
        • 1970-01-01
        • 2020-09-19
        • 2011-10-28
        • 1970-01-01
        • 1970-01-01
        • 2018-05-31
        相关资源
        最近更新 更多