One colorbar for all subplots using cartopy mapping via PyCall

I try to generate a shared colorbar for several subplots using cartopy via PyCall and PyPlot but haven’t succeeded. Here’s a minimal code example with separate colorbars:

using PyCall, PyPlot

plt = pyimport("matplotlib.pyplot")
ccrs = pyimport("cartopy.crs")
cfeature = pyimport("cartopy.feature")
cput = pyimport("cartopy.util")

proj1 = ccrs.PlateCarree();
proj3 = ccrs.EuroPP();

lons = [lon for lon in -10.:2.5:27.5]
arr = rand(16,16,2)

fig = plt.figure()
for i in 1:2
    ax = plt.subplot(1,2,i, projection=proj3)
    wrap_data, wrap_lon = cput.add_cyclic_point(arr[:,:,i], coord=lons, axis=1)
    ax.add_feature(cfeature.OCEAN, zorder=100, edgecolor="k", lw=.5, facecolor=cfeature.COLORS["land"]) 
    p = ax.pcolormesh(wrap_lon, lat, wrap_data, transform=proj1, cmap="RdBu_r")
    cbar = plt.colorbar(p, shrink=0.9, orientation="horizontal") 
end
plt.tight_layout()

image

My main problem is that p is only valid inside the loop, once I move cbar out it gives error, and I haven’t had an idea how to deal with it … Any help is much appreciated.

You are using Julia V1.4 or earlier, right?
With Julia 1.5 it should work out-of-the-box because the interactive scoping rules have been changed.
In earlier Julia versions, you need to add

global p

before the for loop, or wrap the whole code into a function.

1 Like

Thank you, I am using V1.5.3 actually, but global p indeed works. Though I still need to figure out how to scale the colorbar. Do you have good suggestions?

arr = rand(16,16,4)

fig = plt.figure()
for i in 1:4
    ax = plt.subplot(2,2,i, projection=proj3)
    wrap_data, wrap_lon = cput.add_cyclic_point(arr[:,:,i], coord=lons, axis=1)
    ax.add_feature(cfeature.OCEAN, zorder=100, edgecolor="k", lw=.5, facecolor=cfeature.COLORS["land"]) 
    global p = ax.pcolormesh(wrap_lon, lat, wrap_data, transform=proj1, cmap="RdBu_r")
end
plt.tight_layout()
cbar = plt.colorbar(p, orientation="horizontal") 

image

The Julia 1.5 scoping has only been changed for interactive usage in the REPL, not when your code is in a file. But you should have received a warning message about the ambiguity of the variable p.

Regarding the color bar scaling I unfortunately cannot help you.

I searched for some py examples and found this would work:

fig.subplots_adjust(bottom=0.25)
cbar_ax = fig.add_axes([0.17, 0.17, 0.65, 0.04])
fig.colorbar(p, cax=cbar_ax, orientation="horizontal")

image

Hopefully the interactive scoping would soon be available not only in the REPL.

No, they are good reasons for the current behavior, see here: Scope of Variables · The Julia Language

1 Like

OIC, thanks for the helpful info.