26

I've been trying to plot an ellipse into an imshow plot. It works, but plotting the ellipse after plotting the image seems to increase xlim and ylim, resulting in a border, which I'd like to get rid of:

Note that there is NO white border directly after calling imshow only.

My code looks as follows:

self.dpi = 100
self.fig = Figure((6.0, 6.0), dpi=self.dpi)
self.canvas = FigureCanvas(self.fig)
self.canvas.setMinimumSize(800, 400)
self.cax = None
self.axes = self.fig.add_subplot(111)
self.axes.imshow(channel1, interpolation="nearest")
self.canvas.draw()
self.axes.plot(dat[0], dat[1], "b-")

I've tried setting the limits before and after calling "plot", with no effect

# get limits after calling imshow
xlim, ylim = pylab.xlim(), pylab.ylim()
...
# set limits before/after calling plot
self.axes.set_xlim(xlim)
self.axes.set_ylim(ylim)

How can I force plot not to increase existing figure limits?

Solution (thanks to Joe):

#for newer matplotlib versions
self.axes.imshow(channel1, interpolation="nearest")
self.axes.autoscale(False)
self.axes.plot(dat[0], dat[1], "b-")

#for older matplotlib versions (worked for me using 0.99.1.1)
self.axes.imshow(channel1, interpolation="nearest")
self.axes.plot(dat[0], dat[1], "b-", scalex=False, scaley=False)
Falko
  • 17,076
  • 13
  • 60
  • 105
soramimo
  • 1,296
  • 1
  • 13
  • 17

1 Answers1

35

What's happening is that the axis is autoscaling to match the extents of each item you plot. Images are autoscaled much tighter than lines, etc (imshow basically calls ax.axis('image')).

Getting the axis limits before and setting them after should have worked. (It's cleaner to just do limits = axes.axis() before and axes.axis(limits) after, though.)

However, if you don't want things to autoscale, it's best to just turn autoscaling off after the initial plot. Try axes.autoscale(False) after plotting the image.

As an example, compare this:

import matplotlib.pyplot as plt
import numpy as np

fig, ax = plt.subplots()
ax.imshow(np.random.random((10,10)))
ax.plot(range(11))
plt.show()

enter image description here


With this:

import matplotlib.pyplot as plt
import numpy as np

fig, ax = plt.subplots()
ax.imshow(np.random.random((10,10)))
ax.autoscale(False)
ax.plot(range(11))
plt.show()

enter image description here

Joe Kington
  • 275,208
  • 71
  • 604
  • 463
  • 3
    Hi Joe, thanks for your detailed explanation! My matplotlib version seems to be too old (matplotlib.__version__ = '0.99.1.1') as it supports neither plt.subplots() nor ax.autoscale, however as you pointed out autoscale=False, I found an [alternative solution](http://stackoverflow.com/questions/7386872/make-matplotlib-autoscaling-ignore-some-of-the-plots) that fixes my problem: each time I use plot after initially calling imshow, I use the keyword arguments scalex=False, scaley=False, which does the right thing! Thanks you! – soramimo Feb 03 '12 at 20:30