Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Matplotlib mixed subplots with plot and pcolor(mesh) to have the same x axis length when colorbar is on

I am wondering if it is possible to have a subplot with a mixture of graphs drawn with plot() and figures drawn with pcolormesh() that would have the same x axis length.

I attached 2 images one when the pcolormesh() subplot does not have the colorbar drawn when the x axes are the same length enter image description here and one that has the colorbar when the pcolormesh() subplot is shrunk so that it accommodates the colorbar. enter image description here

I would like to have the colorbar, but it should be extending the length of the whole plot and not shrink the subplot.

Is this possible without sub-classing any of the current classes?

like image 221
Bogdan Avatar asked May 05 '14 16:05

Bogdan


People also ask

How can you plot subplots with different sizes?

Create Different Subplot Sizes in Matplotlib using Gridspec The GridSpec from the gridspec module is used to adjust the geometry of the Subplot grid. We can use different parameters to adjust the shape, size, and number of columns and rows.

What is the use of Xticks () and Yticks () in plotting?

The xticks() and yticks() function takes a list object as argument. The elements in the list denote the positions on corresponding action where ticks will be displayed. This method will mark the data points at the given positions with ticks.


1 Answers

Sure, it's possible!

What's happening is that a new axes is being created for the colorbar, and the space is being taken from the axes that pcolormesh is plotted in. If you don't want this to happen, you can specify an axes object for the colorbar to go in. Alternately, you could just use a horizontal colorbar.

At any rate, let's reproduce your problem with stand-alone data:

import matplotlib.pyplot as plt
import numpy as np
np.random.seed(1977)

# Generate some interesting-looking random data...
num = 200
grid = np.random.normal(0, 1, (20, num)).cumsum(axis=1).cumsum(axis=0)
x = np.linspace(0, 360, num)
y1 = np.random.normal(0, 1, num).cumsum()
y2 = np.random.normal(0, 1, num).cumsum()

# Plot on three seperate axes
fig, axes = plt.subplots(nrows=3, sharex=True)
axes[0].plot(x, y1)
axes[1].plot(x, y2)
im = axes[2].imshow(grid, extent=[0, 360, 0, 20], aspect='auto')
fig.colorbar(im)

plt.show()

enter image description here


A quick fix is to just use a horizontal colorbar:

import matplotlib.pyplot as plt
import numpy as np
np.random.seed(1977)

# Generate some interesting-looking random data...
num = 200
grid = np.random.normal(0, 1, (20, num)).cumsum(axis=1).cumsum(axis=0)
x = np.linspace(0, 360, num)
y1 = np.random.normal(0, 1, num).cumsum()
y2 = np.random.normal(0, 1, num).cumsum()

# Plot on three seperate axes
fig, axes = plt.subplots(nrows=3, sharex=True)
axes[0].plot(x, y1)
axes[1].plot(x, y2)
im = axes[2].imshow(grid, extent=[0, 360, 0, 20], aspect='auto')
fig.colorbar(im, orientation='horizontal')

plt.show()

enter image description here


Alternately, you can manually add another axes for the colorbar. We'll also adjust things a bit to make more room.

(Side note: Don't use tight_layout after making the extra axes. We're no longer working with a nice grid of subplots once we add the additional one, so tight_layout will not work correctly. It's safe to use it before, though you may want to modify the call to subplots_adjust in that case.)

import matplotlib.pyplot as plt
import numpy as np
np.random.seed(1977)

# Generate some interesting-looking random data...
num = 200
grid = np.random.normal(0, 1, (20, num)).cumsum(axis=1).cumsum(axis=0)
x = np.linspace(0, 360, num)
y1 = np.random.normal(0, 1, num).cumsum()
y2 = np.random.normal(0, 1, num).cumsum()

# Plot on three seperate axes
fig, axes = plt.subplots(nrows=3, sharex=True)
axes[0].plot(x, y1)
axes[1].plot(x, y2)
im = axes[2].imshow(grid, extent=[0, 360, 0, 20], aspect='auto')

# Make some room for the colorbar
fig.subplots_adjust(left=0.07, right=0.87)

# Add the colorbar outside...
box = axes[2].get_position()
pad, width = 0.02, 0.02
cax = fig.add_axes([box.xmax + pad, box.ymin, width, box.height])
fig.colorbar(im, cax=cax)

plt.show()

enter image description here

like image 176
Joe Kington Avatar answered Nov 15 '22 08:11

Joe Kington