Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bokeh heatmap from Pandas confusion matrix

How can a Pandas DataFrame be shown as a Bokeh heatmap?

https://docs.bokeh.org/en/latest/docs/user_guide/categorical.html#heat-maps shows some example, but trying to modify always only gave an empty plot.

Example confusion matrix:

df = pd.DataFrame([[10, 0, 1], [1, 10, 0], [1, 1, 9]], 
                  columns=['A', 'B', 'C'], 
                  index=['A', 'B', 'C'])
df.index.name = 'Treatment'
df.columns.name = 'Prediction'
like image 835
serv-inc Avatar asked Oct 24 '25 23:10

serv-inc


1 Answers

First import packages and prepare data.frame :

import pandas as pd

from bokeh.io import output_file, show
from bokeh.models import BasicTicker, ColorBar, LinearColorMapper, ColumnDataSource, PrintfTickFormatter
from bokeh.plotting import figure
from bokeh.transform import transform

df = pd.DataFrame(
    [[10, 0, 1], [1, 10, 0], [1, 1, 9]],
    columns=['A', 'B', 'C'],
    index=['A', 'B', 'C'])
df.index.name = 'Treatment'
df.columns.name = 'Prediction'

To use my solution you have to stack the data.frame :

# Prepare data.frame in the right format
df = df.stack().rename("value").reset_index()

Now, we can create the plot :

# here the plot :
output_file("myPlot.html")

# You can use your own palette here
colors = ['#d7191c', '#fdae61', '#ffffbf', '#a6d96a', '#1a9641']

# Had a specific mapper to map color with value
mapper = LinearColorMapper(
    palette=colors, low=df.value.min(), high=df.value.max())
# Define a figure
p = figure(
    plot_width=800,
    plot_height=300,
    title="My plot",
    x_range=list(df.Treatment.drop_duplicates()),
    y_range=list(df.Prediction.drop_duplicates()),
    toolbar_location=None,
    tools="",
    x_axis_location="above")
# Create rectangle for heatmap
p.rect(
    x="Treatment",
    y="Prediction",
    width=1,
    height=1,
    source=ColumnDataSource(df),
    line_color=None,
    fill_color=transform('value', mapper))
# Add legend
color_bar = ColorBar(
    color_mapper=mapper,
    location=(0, 0),
    ticker=BasicTicker(desired_num_ticks=len(colors)))

p.add_layout(color_bar, 'right')

show(p)

*Note : I use a more complete solution than just call HeatMap from the bokeh library because 1) you have more control on parameters like this, 2) there are lot of incompatibilities with Bokeh, Pandas, etc and this is the only solution working with my configuration.

like image 87
Thomas Avatar answered Oct 27 '25 12:10

Thomas



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!