title: How to create Matplotlib figure with image and profile plots that fit together?
body: <p>I would like to plot 2d data as an image, with profile plots through along the x and y axis displayed below and to the side. It's a pretty common way to display data so there may be an easier way to approach this. I would like to find the most simple and robust way that does so correctly, and without using anything outside of matplotlib (though I would be interested in knowing of other packages that may be particularly relevant). In particular, the method should work without changing anything if the shape (aspect ratio) of the data changes.</p>
  
  <p>My main issue is getting the side plots to scale correctly so their borders match up with main plot.</p>
  
  <p>Example code:</p>
  
  <pre><code>import numpy as np
  import matplotlib.pyplot as plt
  import matplotlib.gridspec as gridspec
  # generate grid and test data
  x, y = np.linspace(-3,3,300), np.linspace(-1,1,100)
  X, Y = np.meshgrid(x,y)
  def f(x,y) :
      return np.exp(-(x**2/4+y**2)/.2)*np.cos((x**2+y**2)*10)**2
  data = f(X,Y)
  
  # 2d image plot with profiles
  h, w = data.shape
  gs = gridspec.GridSpec(2, 2,width_ratios=[w,w*.2], height_ratios=[h,h*.2])
  ax = [plt.subplot(gs[0]),plt.subplot(gs[1]),plt.subplot(gs[2])]
  bounds = [x.min(),x.max(),y.min(),y.max()]
  ax[0].imshow(data, cmap='gray', extent = bounds, origin='lower')
  ax[1].plot(data[:,w/2],Y[:,w/2],'.',data[:,w/2],Y[:,w/2])
  ax[1].axis([data[:,w/2].max(), data[:,w/2].min(), Y.min(), Y.max()])
  ax[2].plot(X[h/2,:],data[h/2,:],'.',X[h/2,:],data[h/2,:])
  plt.show()
  </code></pre>
  
  <p>As you can see from the output below, the way things are scaled the image to the right does not properly match the boundaries.</p>
  
  <p>Partial solutions: </p>
  
  <p>1) Manually play with the figure size to find the right aspect ratio so that it appears correctly (could do automatically using the image ratio + padding + the width ratios used?). Seems tacky when there are already so many options for packing that are supposed to take care of these things automatically. <strong>EDIT:</strong> <code>plt.gcf().set_figheight(f.get_figwidth()*h/w)</code> seems to work if padding is not changed.</p>
  
  <p>2) Add <code>ax[0].set_aspect('auto')</code> , which then makes boundaries line up, but the image no longer has the correct aspect ratio.</p>
  
  <p>Output from code sample above:
  <a href="https://i.stack.imgur.com/IghBn.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/IghBn.png" alt="Example output"></a></p>