DrSAR
DrSAR

Reputation: 1552

overlay matplotlib imshow with line plots that are arranged in a grid

I would like to plot a number of curves over an image

Using this code I am reasonably close:

G=plt.matplotlib.gridspec.GridSpec(64,1)
fig = plt.figure()
plt.imshow(img.data[:,:],cmap='gray')
plt.axis('off')
plt.axis([0,128,0,64])
for i in arange(64):
    fig.add_subplot(G[i,0])
    plt.axis('off')
    # note that vtc.data.shape = (64, 128*400=51200)
    # so every trace for each image pixel is 400 points long
    plt.plot(vtc.data[i,:])
    plt.axis([0, 51200, 0, 5])

The result that I am getting looks like this: lineplots over image

The problem is that while I seem to be able to get rid of all the padding in the horizontal (x) direction, there is different amount of padding in the image and the stacked plots in the vertical direction.

I tried using

ax = plt.gca()
ax.autoscale_view('tight')

but that didn't reduce the margin either.

How can I get a grid of m-by-n line plots to line up precisely with a blown up (by factor f) version of an image with dimensions (fm)-by-(fn)?


UPDATE and Solution: The answer by @RutgerKassies works quite well. I achieved it using his code like so:

fig, axs = plt.subplots(1,1,figsize=(8,4))
axs.imshow(img.data[:,:],cmap='gray', interpolation='none')
nplots = 64
fig.canvas.draw()
box = axs._position.bounds
height = box[3] / nplots
for i in arange(nplots):
    tmpax = fig.add_axes([box[0], box[1] + i * height, box[2], height])
    tmpax.set_axis_off()
    # make sure to get image orientation right and 
    tmpax.plot(vtc.data[nplots-i-1,:],alpha=.3)
    tmpax.set_ylim(0,5)
    tmpax.set_xlim(0, 51200)

improved image

Upvotes: 3

Views: 10157

Answers (1)

Rutger Kassies
Rutger Kassies

Reputation: 64443

I think the easiest way is to use the boundaries from your 'imshow axes' to manually calculate the boundaries of all your 'lineplot axes':

import matplotlib.pyplot as plt
import numpy as np

fig, axs = plt.subplots(1,1,figsize=(15,10))

axs.imshow(np.random.rand(50,100) ,cmap='gray', interpolation='none', alpha=0.3)

nplots = 50

fig.canvas.draw()

box = axs._position.bounds
height = box[3] / nplots

for i in arange(nplots):

    tmpax = fig.add_axes([box[0], box[1] + i * height, box[2], height])
    tmpax.set_axis_off()

    tmpax.plot(np.sin(np.linspace(0,np.random.randint(20,1000),1000))*0.4)
    tmpax.set_ylim(-1,1)

The above code seems nice, but i do have some issues with the autoscale chopping off part of the plot. Try removing the last line to see the effect, im not sure why thats happening.

enter image description here

Upvotes: 6

Related Questions