I have the following pandas dataframe
import pandas as pd
df_dict = {'index': [0, 1, 2, 3, 4, 5, 6, 7, 8], 'columns': ['from', 'moving', 'N', 'total', 'perc', 'helper', 'label'], 'data': [['0', 'no', 29, 39, 74.35897435897436, 'all', '74.4 %'], ['0', 'yes', 10, 39, 25.641025641025642, 'all', '25.6 %'], ['1', 'no', 77, 84, 91.66666666666667, 'all', '91.7 %'], ['1', 'yes', 7, 84, 8.333333333333334, 'all', '8.3 %'], ['2', 'no', 6, 6, 100.0, 'all', '100.0 %'], ['3', 'no', 19, 25, 76.0, 'all', '76.0 %'], ['3', 'yes', 6, 25, 24.0, 'all', '24.0 %'], ['4', 'no', 30, 45, 66.66666666666667, 'all', '66.7 %'], ['4', 'yes', 15, 45, 33.333333333333336, 'all', '33.3 %']]}
df = pd.DataFrame(index=df_dict['index'], columns=df_dict['columns'], data=df_dict['data'])
I am using the following code:
import plotly.express as px
def pl(dt, color_col, title, facet_col=None,
color_discrete_map=dict(zip(['4', '0', '2', '3', '1'],['#003898', '#164461','#61B3C1', '#8ED3F6 ','#8DD1C8']))):
px.bar(dt, x='helper', y='perc', color=color_col, facet_col=facet_col, category_orders={col: sorted(dt_temp[col].unique())},
color_discrete_map=color_discrete_map, title=title, text='label').show()
pl(dt=df, facet_col='from',
color_col='from', title='title')
In order to produce this plot:
I would like to add a shading of the specified color in the color_discrete_map
with respect to the moving
column of the df
, so that the no
's are a bit more faded.
How could I do that with plotly
express?
I don't believe that you can access the text font through any of the px.bar
parameters. However, you can save your px.bar in an object called fig
, then directly modify the each bar object through fig.data[0]
, fig.data[1]
, ... fig.data[n-1]
for n bars.
The text color for each of these bars can be modified by passing a dictionary to the textcolor
attribute of each of bar objects fig.data[0]... fig.data[n-1]
. For example, you could modify the text of the first bar to be red with the line: fig.data[0].textcolor: {'color': 'red'}
. This lends itself to looping through each fig.data bar object and modifying the textcolor attribute to be the desired color.
The last part is to make your color a shade of the bar color. I am not that familiar with hex color codes, so it makes the most sense to convert each hex color code to an rgb tuple of three values, and find the intermediate color between this value and white. plotly.colors conveniently has the methods hex_to_rgb
and find_intermediate_color
so we can use these to convert each of your hex colors to rgb, then find the rgb tuple between that color and white which is rgb(255,255,255)
.
To be consistent with the way you've structured your program, I put the code setting the textfont attributes in your pl
function.
import pandas as pd
import plotly.express as px
from plotly.colors import hex_to_rgb, find_intermediate_color
df_dict = {'index': [0, 1, 2, 3, 4, 5, 6, 7, 8], 'columns': ['from', 'moving', 'N', 'total', 'perc', 'helper', 'label'], 'data': [['0', 'no', 29, 39, 74.35897435897436, 'all', '74.4 %'], ['0', 'yes', 10, 39, 25.641025641025642, 'all', '25.6 %'], ['1', 'no', 77, 84, 91.66666666666667, 'all', '91.7 %'], ['1', 'yes', 7, 84, 8.333333333333334, 'all', '8.3 %'], ['2', 'no', 6, 6, 100.0, 'all', '100.0 %'], ['3', 'no', 19, 25, 76.0, 'all', '76.0 %'], ['3', 'yes', 6, 25, 24.0, 'all', '24.0 %'], ['4', 'no', 30, 45, 66.66666666666667, 'all', '66.7 %'], ['4', 'yes', 15, 45, 33.333333333333336, 'all', '33.3 %']]}
df = pd.DataFrame(index=df_dict['index'], columns=df_dict['columns'], data=df_dict['data'])
bar_color_map = dict(zip(['4', '0', '2', '3', '1'],['#003898', '#164461','#61B3C1', '#8ED3F6','#8DD1C8']))
def pl(dt, color_col, title, facet_col=None, color_discrete_map=bar_color_map):
fig = px.bar(dt, x='helper', y='perc', color=color_col, facet_col=facet_col,
# category_orders={col: sorted(dt_temp[col].unique())},
category_orders={color_col: sorted(dt[color_col].unique())},
color_discrete_map=color_discrete_map, title=title, text='label')
## set fig.data.textfont attribute
for bar_number in range(len(fig.data)):
bar_color = hex_to_rgb(bar_color_map[str(bar_number)])
shaded_text_color = find_intermediate_color(bar_color,(255,255,255),0.5)
shaded_int_rgb_color = tuple([int(text_color) for text_color in shaded_text_color])
# print('rgb'+str(shaded_int_rgb_color))
fig.data[bar_number].textfont = {'color': 'rgb'+str(shaded_int_rgb_color)}
fig.show()
pl(dt=df, facet_col='from', color_col='from', title='title')
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.