简体   繁体   中英

How to add a common colorbar to subplots in Matplotlib and change their limits together

I'm trying to have three pseudocolor subplots side by side, with one colorbar for subplots #1 and #2 and a second colorbar for #3. I'd also like the color limits (clim) to be set so it's the same for the first two (so the first colorbar would reflect the values of both subplots #1 and #2).

Here's what I have so far:

import numpy as np
import matplotlib.pyplot as plt
plt.ion()
import matplotlib as mpl


data1 = np.random.random((10,10))
data2 = 2.*np.random.random((10,10))
data3 = 3.*np.random.random((10,10))


f, (ax1, ax2, ax3) = plt.subplots(1, 3, sharey=True)

imgplot1 = ax1.pcolormesh(data1, edgecolors='None')

imgplot2 = ax2.pcolormesh(data2, edgecolors='None')

plt.subplots_adjust(hspace=0.1, wspace=0.1)
cax2, kw = mpl.colorbar.make_axes([ax1, ax2])
plt.colorbar(imgplot2, cax=cax2, **kw)
imgplot2.set_clim(0,20)

imgplot3 = ax3.pcolormesh(data3, edgecolors='None')
cax3, kw = mpl.colorbar.make_axes([ax3])
plt.colorbar(imgplot3, cax=cax3, **kw)

imgplot2.set_clim(0,20) sets subplot #2 (though I have seen a backend-dependent issue where it doesn't always update unless you interact with the plot), but is there a way to link the color limits of two subplots so one colorbar can describe both plots?

update: To clarify, I'm looking for the ability to re-adjust clim after the plots have already been created.

Specify vmin and vmax in both your calls to pcolormesh of the axes where the data should be visualized with a common colorbar.

In your case:

opts = {'vmin': 0, 'vmax': 20, 'edgecolors': 'none'}
imgplot1 = ax1.pcolormesh(data1, **opts)
imgplot2 = ax2.pcolormesh(data2, **opts)

And then get rid of the call to imgplot2.set_clim(0,20) . Alternatively, you could call set_clim on imgplot1 too, using the same parameters. It would have the same effect.

Continuing on your comment below this answer, you could just as easily replace your single call to imgplot2.set_clim with a call to a custom function that updates the clim of both axes:

def update_clims(vmin, vmax, axes):
    for ax in axes:
        ax.set_clim(vmin, vmax)

If you really wanted to, you could rebind the set_clim method of the Axes class to perform the functionality above, provided you add a list of axes that have shared z-data. But that seems like a lot of work for an otherwise easy to implement function. And since you're calling an update of the clim already once on one axes, you could just as easily replace it with that call.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM