I'm trying to make a figure of some xyz data. I need to show different regions of the data using a colormap, as well as an integrated area in a plot alongside. Here's my example code:
import matplotlib.pyplot as plt
import numpy as np
#Generate some arbitrary xyz data
def gauss(x, y, mx, my, sx, sy):
return np.exp(-(x-mx)**2/(2*sx**2))*np.exp(-(y-my)**2/(2*sy**2))
xmin, xmax, ymin, ymax = 0.97, 1.04, 2.60, 3.05
x, y = np.meshgrid(np.linspace(xmin, xmax, 1000), np.linspace(ymin, ymax, 1000))
data = gauss(x, y, 1, 3, 0.01, 0.01) + gauss(x, y, 1, 2.7, 0.01, 0.01)
#Plot the data
fig = plt.figure()
ax1 = fig.add_subplot(121)
ax1.imshow(data, extent=[xmin, xmax, ymin, ymax], origin="lower")
ax2 = fig.add_subplot(122)
ax2.plot(np.sum(data, axis=1),y[:,0])
ax2.set_ylim(ax1.get_ylim())
ax2.set_yticklabels([])
plt.show()
This code produces a nice figure:
Now I'd like to focus in on just the two regions with significant z-value. To do this, I split the two subplots into four subplots, with the top row focusing in on the top peak, and the bottom row focusing in on the bottom peak. Using the same data, here's the code:
#Plot the data
fig = plt.figure(figsize=(4,10))
ax1 = fig.add_subplot(221)
ax1.imshow(data, extent=[xmin, xmax, ymin, ymax], origin="lower")
ax1.set_ylim([2.60, 2.75])
ax2 = fig.add_subplot(222)
ax2.plot(np.sum(data, axis=1),y[:,0])
ax2.set_ylim(ax1.get_ylim())
ax2.set_yticklabels([])
ax3 = fig.add_subplot(223)
ax3.imshow(data, extent=[xmin, xmax, ymin, ymax], origin="lower")
ax3.set_ylim([2.95, 3.05])
ax2 = fig.add_subplot(224)
ax2.plot(np.sum(data, axis=1),y[:,0])
ax2.set_ylim(ax3.get_ylim())
ax2.set_yticklabels([])
The figure produced has axes which don't line up with one another:
What I'd like to have is the two subplots on the left have x-axes which match, the two subplots on the right to have the same size x-axis, and in both rows I'd like to have the curves on the right to have the same y-axis size as its corresponding image to the left. I'd also like to keep the aspect ratio of the plots on the left equal, which rules out the possible solution discussed here.
I can resize the window to satisfy some of these conditions, but I can never get the y-axes of the plots on the right to stay the same size as the images at left. I've tried using GridSpec
, subplot2grid
, and generating the axes on the right manually using appropriate Bbox
bounds taken from the image subplots on the left, but these methods all give me the same issue. I've also tried using the sharedx
and sharedy
options when creating axes, and while it seems to make the y-axes of the images on the left match the y-axes of the plots on the right, it does so by zooming in on the image, which is not what I want.
I made an example of what I want using Inkscape: Fig. 3.
EDIT:
It was suggested that I try to use set_aspect
to adjust the aspect of the plots on the right so that the y-axis size is the same as what is on the left, but this doesn't work:
asp = np.diff(ax2.get_xlim())[0]/np.diff(ax2.get_ylim())[0]
ax2.set_aspect(asp)
While this does seem to prevent the subplot from being larger than the subplot on the left, it doesn't make the axes the same size. Again upon resizing the window I can now make the subplot on the top right the same size as the one in top left, but then the x-axes of the top left and bottom left don't match.