Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

like image 450
DrSAR Avatar asked Dec 05 '25 14:12

DrSAR


1 Answers

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

like image 81
Rutger Kassies Avatar answered Dec 08 '25 02:12

Rutger Kassies



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!