Search code examples
pythonplotlyimshow

How to use respective colorbar when using facet_col with plotly.express?


I have a data which has three variables whose magnitudes are different.

I'm trying to apply animation_frame and facet_col to make them animate at the same time.

Here's the code:

import plotly.express as px
import xarray as xr

# Load xarray from dataset included in the xarray tutorial
ds = xr.tutorial.open_dataset('eraint_uvz').sel(level=500)

# convert Dataset to DataArray for animation
data = ds.to_array().transpose('month', ...)

# fix the bug
#   TypeError: %d format: a real number is required, not str
plot_data = data.assign_coords({'variable': range(len(data['variable']))})
fig = px.imshow(plot_data, animation_frame='month', facet_col='variable', color_continuous_scale='viridis')

# set variable back to string
#   https://community.plotly.com/t/cant-set-strings-as-facet-col-in-px-imshow/60904
for k in range(len(data['variable'])):
    fig.layout.annotations[k].update(text = data['variable'].values[k])
    
fig.show()

By default, they share the same colorbar like below. Is it possible to make three colorbars (even different cmaps) with manual zmin/zmax values?

img


Solution

  • I found the similar question and modified it.

    It looks nice to me. Only the titles are in the wrong order.

    fig = px.imshow(plot_data, animation_frame='month',
                    facet_col='variable', facet_col_wrap=1,
                    color_continuous_scale='viridis')
    
    # set variable back to string
    #   https://community.plotly.com/t/cant-set-strings-as-facet-col-in-px-imshow/60904
    for k in range(len(data['variable'])):
        fig.layout.annotations[k].update(text = data['variable'].values[k])
    
    
    # update traces to use different coloraxis
    for i, t in enumerate(fig.data):
        t.update(coloraxis=f"coloraxis{i+1}")
    for fr in fig.frames:
        # update each of the traces in each of the animation frames
        for i, t in enumerate(fr.data):
            t.update(coloraxis=f"coloraxis{i+1}")
    
    # position / config all coloraxis
    fig.update_layout(
        coloraxis={"colorbar": {"x": 1, "len": 0.3, "y": 0.85}},
        coloraxis2={
            "colorbar": {
                "x": 1,
                "len": 0.3,
                "y": 0.5,
            },
            "colorscale": 'Thermal',
        },
        coloraxis3={
            "colorbar": {"x": 1, "len": 0.3, "y": 0.15},
            "colorscale": 'Blues',
        },
    )
    
    fig.show()
    

    img