如何在分组的绘图条形图中为条形图着色
How to color bars in grouped plotly bar chart
所以,我想在 Python 3.9 中创建一个带有 Plotly.express 的条形图。
我用 pandas 创建了以下 table:
idx cat1 cat2 cat3 cat4
0 A 0.98 0.93 0.550 1.00
1 B 0.92 0.80 0.865 1.00
2 C 0.91 0.87 0.955 0.96
我有以下代码:
# df is the pandas table
fig = px.bar(df,
x = 'idx',
y=['cat1', 'cat2', 'cat3', 'cat4']
)
colors = ['#dc1a22', ] * 12
colors[2] = '#000000'
fig.update_traces(marker_color = colors, marker_line_color='rgb(8,48,107)',
marker_line_width=1.5, opacity=0.6)
fig.update_layout(barmode='group')
我想为#dc1a22 中所有组中的所有条着色,除了第三位置的那个(颜色[2])。
实际情况是,第一组和第二组中的所有柱都在#dc1a22 中,第三组中的所有柱都在#000000 中。
是否可以为分组图表中的单个条形图着色?
可能很重要:将来我会尝试根据它们的值为条形图着色。
(0-0.5 -> 红色,0.5-0.9 -> 黄色,0.9-1 -> 绿色)
您可以做的是使用循环一次添加一个轨迹,并将颜色列表和相应列名列表传递给每个 go.bar
对象。不幸的是,需要重置条的默认宽度,并且在分组模式下,条以 overlay
模式绘制(这意味着如果您设置每个条的宽度而不更改偏移量,它们将重叠)。
因此还需要调整偏移量以确保条形很好地围绕 x 轴上的每个 idx 类别居中。条形宽度为 0.2 时,将四个条形中的每一个的偏移量分别设置为 [-0.4、-0.2、0、0.2]。这可能适用于任何宽度。
import numpy as np
import pandas as pd
import plotly.graph_objs as go
## recreate the data
df = pd.DataFrame({'idx':['A','B','C'], 'cat1':[0.98,0.92,0.91], 'cat2':[0.93,0.80,0.87], 'cat3':[0.55,0.865,0.955], 'cat4':[1,1,0.96]})
fig = go.Figure()
indexes = ['A','B','C']
groups = ['cat1','cat2','cat3','cat4']
colors = ['#dc1a22','#dc1a22','#000000','#dc1a22']
## this can be generalized a bit better
width = 0.2
offset = [-0.4,-0.2,0,0.2]
for i in indexes:
for g, c, o in zip(groups, colors, offset):
fig.add_trace(
go.Bar(x=df['idx'], y=df[g], marker_color=c, width=width, offset=o)
)
fig.update_traces(
marker_line_color='rgb(8,48,107)',
marker_line_width=1.5,
opacity=0.6
)
fig.update_layout(
xaxis_title='idx',
yaxis_title='value',
barmode='group',
showlegend=False
)
fig.show()
所以,我想在 Python 3.9 中创建一个带有 Plotly.express 的条形图。 我用 pandas 创建了以下 table:
idx cat1 cat2 cat3 cat4
0 A 0.98 0.93 0.550 1.00
1 B 0.92 0.80 0.865 1.00
2 C 0.91 0.87 0.955 0.96
我有以下代码:
# df is the pandas table
fig = px.bar(df,
x = 'idx',
y=['cat1', 'cat2', 'cat3', 'cat4']
)
colors = ['#dc1a22', ] * 12
colors[2] = '#000000'
fig.update_traces(marker_color = colors, marker_line_color='rgb(8,48,107)',
marker_line_width=1.5, opacity=0.6)
fig.update_layout(barmode='group')
我想为#dc1a22 中所有组中的所有条着色,除了第三位置的那个(颜色[2])。
实际情况是,第一组和第二组中的所有柱都在#dc1a22 中,第三组中的所有柱都在#000000 中。
是否可以为分组图表中的单个条形图着色?
可能很重要:将来我会尝试根据它们的值为条形图着色。
(0-0.5 -> 红色,0.5-0.9 -> 黄色,0.9-1 -> 绿色)
您可以做的是使用循环一次添加一个轨迹,并将颜色列表和相应列名列表传递给每个 go.bar
对象。不幸的是,需要重置条的默认宽度,并且在分组模式下,条以 overlay
模式绘制(这意味着如果您设置每个条的宽度而不更改偏移量,它们将重叠)。
因此还需要调整偏移量以确保条形很好地围绕 x 轴上的每个 idx 类别居中。条形宽度为 0.2 时,将四个条形中的每一个的偏移量分别设置为 [-0.4、-0.2、0、0.2]。这可能适用于任何宽度。
import numpy as np
import pandas as pd
import plotly.graph_objs as go
## recreate the data
df = pd.DataFrame({'idx':['A','B','C'], 'cat1':[0.98,0.92,0.91], 'cat2':[0.93,0.80,0.87], 'cat3':[0.55,0.865,0.955], 'cat4':[1,1,0.96]})
fig = go.Figure()
indexes = ['A','B','C']
groups = ['cat1','cat2','cat3','cat4']
colors = ['#dc1a22','#dc1a22','#000000','#dc1a22']
## this can be generalized a bit better
width = 0.2
offset = [-0.4,-0.2,0,0.2]
for i in indexes:
for g, c, o in zip(groups, colors, offset):
fig.add_trace(
go.Bar(x=df['idx'], y=df[g], marker_color=c, width=width, offset=o)
)
fig.update_traces(
marker_line_color='rgb(8,48,107)',
marker_line_width=1.5,
opacity=0.6
)
fig.update_layout(
xaxis_title='idx',
yaxis_title='value',
barmode='group',
showlegend=False
)
fig.show()