Hello everyone
I used plotly.figure_factory
to plot the following heatmap:
But what I want is to colorscale each column individually. Something like this:
(done in Excel)
Notice how for example in column A, the highest value 52 [A4] is darkest among column A, and value 30 [A2] is lightest, while in column D the highest value 34 [D5] is darkest among column D, and the value 8 D[3] is the lightest.
Can this be achievable in plotly?
Thank for you very much in advance!
I actually managed to do it with the help of this answer . I.e. by scaling each column by its max
value, and providing the raw values in the βtextβ and annotation_text
arguments:
def _scale(column, new_range):
old_range = (column.min(), column.max())
return (((column - old_range[0]) * (new_range[1] - new_range[0])) / (old_range[1] - old_range[0])) + new_range[0]
ff.create_annotated_heatmap(z=(hm.apply(lambda col: _scale(col, (0, 1)))).values,
annotation_text=hm.values,
text=hm.values,
x=hm.columns.to_list(),
y=hm.index.to_list(),
hoverinfo='x+y+text',
colorscale='Blues')
giyama
October 2, 2023, 6:12pm
3
I changed the code from the documentation a bit, and it worked:
from dash import Dash, dash_table, html
import pandas as pd
from collections import OrderedDict
wide_data = [
{'Firm': 'Acme', '2017': 13, '2018': 5, '2019': 10, '2020': 4},
{'Firm': 'Olive', '2017': 3, '2018': 3, '2019': 13, '2020': 3},
{'Firm': 'Barnwood', '2017': 6, '2018': 7, '2019': 3, '2020': 6},
{'Firm': 'Henrietta', '2017': -3, '2018': -10, '2019': -5, '2020': -6},
]
df = pd.DataFrame(wide_data)
app = Dash(__name__)
def discrete_background_color_bins(df, n_bins=5, columns='all'):
import colorlover
bounds = [i * (1.0 / n_bins) for i in range(n_bins + 1)]
if columns == 'all':
if 'id' in df:
df_numeric_columns = df.select_dtypes('number').drop(['id'], axis=1)
else:
df_numeric_columns = df.select_dtypes('number')
else:
df_numeric_columns = df[columns]
styles = []
for column in df_numeric_columns:
df_max = df_numeric_columns[[column]].max().max()
df_min = df_numeric_columns[[column]].min().min()
ranges = [
((df_max - df_min) * i) + df_min
for i in bounds
]
for i in range(1, len(bounds)):
min_bound = ranges[i - 1]
max_bound = ranges[i]
backgroundColor = colorlover.scales[str(n_bins)]['seq']['YlOrRd'][i - 1]
color = 'white' if i > len(bounds) / 2. else 'inherit'
styles.append({
'if': {
'filter_query': (
'{{{column}}} >= {min_bound}' +
(' && {{{column}}} < {max_bound}' if (i < len(bounds) - 1) else '')
).format(column=column, min_bound=min_bound, max_bound=max_bound),
'column_id': column
},
'backgroundColor': backgroundColor,
'color': color
})
return styles
styles = discrete_background_color_bins(df, columns=['2017', '2018', '2019', '2020'])
app.layout = html.Div([
dash_table.DataTable(
data=df.to_dict('records'),
sort_action='native',
columns=[{'name': i, 'id': i} for i in df.columns],
style_data_conditional=styles
)
])
if __name__ == '__main__':
app.run(debug=True)