Interactive Portrait Plot
A portrait plot (also known as a heatmap or matrix plot) displays data in a grid format where each cell represents a value through color intensity. Portrait plots are particularly effective for comparing multiple models across multiple variables, visualizing error patterns, and identifying systematic biases in model performance.
The interactive portrait plots in ESMBenchmarkViz support annotations, custom colormaps, tooltips, clickable cells, and export capabilities, making them ideal for model evaluation and intercomparison projects.
This notebook demonstrates key features with practical examples for Earth System Model evaluation.
Detailed API description can be found here.
[1]:
from bokeh.plotting import output_file, save, output_notebook
[2]:
from ESMBenchmarkViz import portrait_plot
[3]:
# Enable Bokeh output in the notebook
output_notebook()
[4]:
import numpy as np
# Test dummy array -- fill random numbers for each array
data1 = np.random.randn(8, 7)
data2 = np.random.randn(8, 7)
data3 = np.random.randn(8, 7)
data4 = np.random.randn(8, 7)
"""
# Test dummy array -- fill same numbers for each array to make sure they are at the right position
data1 = np.full((8, 7), -2)
data2 = np.full((8, 7), -1)
data3 = np.full((8, 7), 1)
data4 = np.full((8, 7), 2)
"""
[4]:
'\n# Test dummy array -- fill same numbers for each array to make sure they are at the right position\ndata1 = np.full((8, 7), -2)\ndata2 = np.full((8, 7), -1)\ndata3 = np.full((8, 7), 1)\ndata4 = np.full((8, 7), 2)\n'
[5]:
data_all = [data1, data2, data3, data4]
xaxis_labels = ['A1', 'A2', 'A3', 'A4', 'A5', 'A6', 'A7']
yaxis_labels = ['B1', 'B2', 'B3', 'B4', 'B5', 'B6', 'B7', 'B8']
xaxis_labels = ['Metric '+x for x in xaxis_labels]
yaxis_labels = ['Model '+y for y in yaxis_labels]
1: Basic usage
Example 1 shows basic usage with a single dataset.
[6]:
p = portrait_plot(
data1,
xaxis_labels=xaxis_labels,
yaxis_labels=yaxis_labels,
width=600,
)
2: Multiple datasets with split cells
Example 2 demonstrates how to display multiple datasets in split cells. Each cell can show up to 4 datasets (top, right, bottom, left - clockwise from top).
[7]:
p = portrait_plot(
data_all, # or [data1, data2, data3, data4] (top, right, bottom, left: clockwise from top)
xaxis_labels=xaxis_labels,
yaxis_labels=yaxis_labels,
legend_labels=['Data1', 'Data2', 'Data3', 'Data4'],
cmap_bounds=[-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5],
width=600,
)
3: Custom colormap and bounds
Example 3 shows how to customize the colormap bounds and legend labels for better data visualization.
[8]:
p = portrait_plot(
data_all,
xaxis_labels=xaxis_labels,
yaxis_labels=yaxis_labels,
legend_labels=['Data1', 'Data2', 'Data3', 'Data4'],
cmap_bounds=[-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5],
width=800, # Larger width
height=600, # Custom height
)
4: Vertical layout with glyph_rows
Example 4 demonstrates vertical stacking of datasets using the glyph_rows parameter instead of the default split-cell layout.
[9]:
p = portrait_plot(
data_all[::-1],
glyph_rows=len(data_all),
xaxis_labels=xaxis_labels,
yaxis_labels=yaxis_labels,
legend_labels=['Data1', 'Data2', 'Data3', 'Data4'][::-1],
cmap_bounds=[-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5],
width=600,
)
5: Save to PNG
Example 5 demonstrates the save functionality. The toolbar now includes a save button for interactive saving, and you can also export static PNG files programmatically.
[10]:
p = portrait_plot(
data1,
static=True,
static_filename = './static_portrait_plot_example.png',
xaxis_labels=xaxis_labels,
yaxis_labels=yaxis_labels,
width=600,
)
6: Practical usage example
Example 6 demonstrates a practical use case with realistic Earth System Model evaluation data, showing model performance across multiple metrics.
[11]:
# Practical example with model performance data
# Simulating RMSE values for different models and metrics
import numpy as np
# More realistic data ranges
model_performance = np.random.uniform(0.5, 2.5, (8, 7)) # RMSE-like values
metrics = ['Temperature', 'Precipitation', 'Wind', 'Humidity', 'Pressure', 'Radiation', 'Cloud']
models = ['ACCESS-CM2', 'E3SM-1-0', 'GFDL-CM4', 'IPSL-CM6A', 'MRI-ESM2', 'NorESM2', 'UKESM1', 'CanESM5']
p = portrait_plot(
model_performance,
xaxis_labels=metrics,
yaxis_labels=models,
cmap_bounds=[0, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0],
width=700,
height=500,
)
7: Save to HTML
[12]:
# set output to static HTML file
output_file(filename="interactive_portrait_plot.html", title="Interactive Portrait Plot")
# save the results to a file
save(p)
# Result: [`interactive_portrait_plot.html`](interactive_portrait_plot.html)
[12]:
'/Users/lee1043/Documents/Research/git/ESMBenchmarkViz/docs/examples/interactive_portrait_plot.html'