1
votes

I am trying to create a figure with 6 subplots all with the same colorbar. I am able to plot everything together, but python automatically adds a color bar to each plot. Therefore, when I attempt to create and add another colorbar that spans the length of the figure, it still has all 6 original colorbars as well as the newly created one. How can I create a colorbar that will span the length of all 6 plots/entire figure, and still delete/remove the single colorbars for each subplot?

Here's my code and an example output (the two middle plots are supposed to be empty at the moment):

fig, axs = plot.subplots(ncols=2, nrows=3, axwidth=5, proj='pcarree')
ax1, ax2, ax3, ax4, ax5, ax6 = axs
axs.format(suptitle=('MAM S06 Change in (m/s)'), 
       coast = True,latlim = (20,50), lonlim = (235,293), innerborders = True)
S06_mam_seas_1.plot.contourf(ax=ax1, levels = levels)
S06_mam_seas_2.plot.contourf(ax=ax2, levels = levels)
S06_mam_seas_3.plot.contourf(ax=ax3, levels = levels)
S06_mam_seas_4.plot.contourf(ax=ax4, levels = levels)
S06_mam_seas_5.plot.contourf(ax=ax5, levels = levels)
S06_mam_seas_6.plot.contourf(ax=ax6, levels = levels)
ax1.set_title(str(Diff1) + ' - ' + str(BASE))
ax2.set_title(str(Diff2) + ' - ' + str(BASE))
ax3.set_title(str(Diff3) + ' - ' + str(BASE))
ax4.set_title(str(Diff4) + ' - ' + str(BASE))
ax5.set_title(str(Diff5) + ' - ' + str(BASE))
ax6.set_title(str(Diff6) + ' - ' + str(BASE))

Output of my images

Output of my images

Here is what happens when I attempt to create and add my own axis: incorrect solution

Thanks!!

2

2 Answers

0
votes

To me, this looks like xarray's faceting capabilities for plots are a nice option. You would first have to concatenate your data arrays along a new dimension, which would be the time period.

import numpy as np
import pandas as pd
import xarray as xr

# Create a dummy representation of your data
S06_mam_seas_1 = xr.DataArray(
    name="s06_change", dims=("lat", "lon"), data=np.random.rand(100, 100)
)
S06_mam_seas_2 = xr.DataArray(
    name="s06_change", dims=("lat", "lon"), data=np.random.rand(100, 100)
)
S06_mam_seas_3 = xr.DataArray(
    name="s06_change", dims=("lat", "lon"), data=np.random.rand(100, 100)
)
S06_mam_seas_4 = xr.DataArray(
    name="s06_change", dims=("lat", "lon"), data=np.random.rand(100, 100)
)
S06_mam_seas_5 = xr.DataArray(
    name="s06_change", dims=("lat", "lon"), data=np.random.rand(100, 100)
)
S06_mam_seas_6 = xr.DataArray(
    name="s06_change", dims=("lat", "lon"), data=np.random.rand(100, 100)
)

# Concatenate the dataarrays along a new dimension
start_years = [1881, 1911, 1941, 2021, 2041, 2071]
end_years = [1910, 1940, 1970, 2050, 2070, 2100]
period = [f"{start} – {end}" for start, end in zip(start_years, end_years)]
S06_mam_seas = xr.concat(
    [
        S06_mam_seas_1,
        S06_mam_seas_2,
        S06_mam_seas_3,
        S06_mam_seas_4,
        S06_mam_seas_5,
        S06_mam_seas_6,
    ],
    dim=pd.Index(period, name="time_period"),
)
# Set some metadata
S06_mam_seas.attrs["long_name"] = "MAM S06 Change"
S06_mam_seas.attrs["units"] = "m/s"

Then, plotting becomes super simple:

levels = np.arange(0, 1, 0.1)
g = S06_mam_seas.plot.contourf(col="time_period", col_wrap=2, levels=levels)
g.set_titles(template="({value}) - (1971 – 2000)")

I am not experienced with plotting maps, so you will need to make some adjustments to the code for setting the projection etc. But in the xarray documentation, there is an example with faceting on maps.

0
votes

First off, by setting one of the initial plotting lines to a variable, say a, we can then use the information from this plot in order to create our colorbar.

Next, ensure that every plotting line has the argument, add_colorbar = False. Now, you have turned off the color bar to all the plots and can proceed in creating your own.

Finally, we can create a color bar that will be added to the entire figure, rather than each individual plot. We can do this by referencing the first plot we made and called a. Now, for example, to plot the first 4 lines of code with one color bar, the code would be:

fig, axs = plot.subplots(ncols=2, nrows=3, 
axwidth=5, proj='pcarree')
ax1, ax2, ax3, ax4, ax5, ax6 = axs
a = S06_mam_seas_1.plot.contourf(ax=ax1,  add_colorbar = False,levels = levels)
S06_mam_seas_2.plot.contourf(ax=ax2, add_colorbar = False,levels = levels)
S06_mam_seas_3.plot.contourf(ax=ax3, add_colorbar = False, levels = levels)
S06_mam_seas_4.plot.contourf(ax=ax4, add_colorbar = False, levels = levels)
S06_mam_seas_5.plot.contourf(ax=ax5, add_colorbar = False, levels = levels)
S06_mam_seas_6.plot.contourf(ax=ax6, add_colorbar = False, levels = levels)


cbar = fig.colorbar(a,  loc="bottom", cmap = cmap, labelsize= 22, label = units, shrink = 1)

This figure was plotted using this technique:

enter image description here