39

I'm plotting some data with matplotlib. I want the plot to focus on a specific range of x-values, so I'm using set_xlim().

Roughly, my code looks like this:

fig=plt.figure()
ax=fig.add_subplot(111)
for ydata in ydatalist:
    ax.plot(x_data,y_data[0],label=ydata[1])
ax.set_xlim(left=0.0,right=1000)
plt.savefig(filename)

When I look at the plot, the x range ends up being from 0 to 12000. This occurs whether set_xlim() occurs before or after plot(). Why is set_xlim() not working in this situation?

Dan
  • 12,157
  • 12
  • 50
  • 84
  • 1
    You could try `plt.xlim(…)`… I remember scratching my head too, few months ago ;-) – tamasgal Jul 18 '13 at 22:00
  • 2
    I made a simple test example using random integers from 0 to 2000 and `ax.set_xlim` properly limits the x-axis from 0 to 1000 for me. – GWW Jul 18 '13 at 22:05
  • Two people left good answers that got deleted. – Dan Jul 18 '13 at 22:20
  • @GWW: Which version of matplotlib are you using? I'm using the RHEL 5 version of matplotlib. – Dan Jul 18 '13 at 22:22
  • 1
    @Dan - Do you have a particular aspect ratio set for the plot? (This happens automatically if you've plotted an image, by the way.) If so, matplotlib will rescale whatever you set to maintain that aspect ratio. Does calling `ax.aspect('auto')` before calling `set_xlim` help? Also, if you want to have matplotlib resize the "outside" of the axes instead of the data limits to maintain a set data aspect ratio, use `ax.set_adjustable('box')`. – Joe Kington Jul 18 '13 at 22:43
  • @Joe Kington: I haven't set a particular aspect ratio. I've gotten it to work; one of the deleted answers fixed my problem (the solution was to use set_xbound()). I'm just waiting for them to repost it, before putting a copy of their answer up myself. – Dan Jul 18 '13 at 22:47
  • 1
    It's odd that `set_xbound` works where `set_xlim` wouldn't. I can't think of a situation where that would normally occur... Out of curiosity, can you post an example that reproduces it? Glad you got things to work, at any rate. – Joe Kington Jul 18 '13 at 22:58
  • 1
    Are you explicitly setting `ax.set_xticks`/`ax.set_xticklabels`? This has the tendency to mess up `ax.xlim` if your ticks/labels are outside of the `.xlim`. – wflynny Jul 18 '13 at 23:10
  • @Bill: I'm not setting either of those. – Dan Jul 18 '13 at 23:17
  • @Joe Kington: I'll post a working example when and if I repost the deleted answer. – Dan Jul 18 '13 at 23:18
  • @Dan: Is it possible you could pastebin your actual code? I'm pretty interested in seeing the bug first hand---I can't seem to reproduce it on my machine. – wflynny Jul 18 '13 at 23:19
  • @Bill: I'll post it when and if I repost the deleted answer. – Dan Jul 18 '13 at 23:20

5 Answers5

18

Out of curiosity, what about switching in the old xmin and xmax?

fig=plt.figure()
ax=fig.add_subplot(111)
ax.plot(x_data,y_data)
ax.set_xlim(xmin=0.0, xmax=1000)
plt.savefig(filename)
esmit
  • 1,748
  • 14
  • 27
  • This works perfectly. Since I'm using an old version of matplotlib, this is almost certainly the problem. – Dan Jul 19 '13 at 20:11
16

The text of this answer was taken from an answer that was deleted almost immediately after it was posted.

set_xlim() limits the data that is displayed on the plot.

In order to change the bounds of the axis, use set_xbound().

fig=plt.figure()
ax=fig.add_subplot(111)
ax.plot(x_data,y_data)
ax.set_xbound(lower=0.0, upper=1000)
plt.savefig(filename)
Dan
  • 12,157
  • 12
  • 50
  • 84
7

In my case the following solutions alone did not work:

ax.set_xlim([0, 5.00])
ax.set_xbound(lower=0.0, upper=5.00)

However, setting the aspect using set_aspect worked, i.e:

ax.set_aspect('auto')
ax.set_xlim([0, 5.00])
ax.set_xbound(lower=0.0, upper=5.00)
wander95
  • 1,298
  • 1
  • 15
  • 22
3

The same thing occurred to me today. My issue was that the data was not in the right format, i.e. not floats. The limits I set (itself floats) became meaningless compared to e.g. strings. After putting float() around the data, everything worked as expected.

Nicouh
  • 99
  • 7
2

I have struggled a lot with the ax.set_xlim() and couldn't get it to work properly and I found out why exactly. After setting the xlim I was setting the xticks and xticklabels (those are the vertical lines on the x-axis and their labels) and this somehow elongated the axis to the needed extent. So if the last tick was at 300 and my xlim was set at 100, it again widened the axis to the 300 just to place the tick there. So the solution was to put it just after the troublesome code:

ax.set_xlabel(label)
ax.set_xticks(xticks)
ax.set_xticklabels(xticks, rotation=60)

ax.set_xlim(xmin=0.0, xmax=100.0)
Dharman
  • 30,962
  • 25
  • 85
  • 135