Why is set_xlim() not setting the x-limits in my figure? - python

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?

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)

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)

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)

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)

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.

Related

Label and tick marks disappear when using log scale in matplotlib python

I need the y-axis of my graph to be on a log scale. When I do so, however, the y-axis' label, tick marks, and title disappear.
plt.figure(2)
plt.semilogy(data2[0, :, 0], sli)
plt.xlabel('n-value')
plt.ylabel('Intensity')
plt.title('Intensity vs. n-shell')
plt.show()
The sli values range from 1.0e-21 to 1.0e-8
When I zoom in far enough though, the label and title actually return but not the tick marks. Don't know if that matters, but thought I'd include it.
Thanks
Edit: As it turns out, the code works fine, just not on my mac laptop. I tested the code on a friends computer running ubuntu and it worked perfectly. So, I guess my log scales don't like macs.
Still, anybody have any suggestions?
"Update" for #ImportanceOfBeingErnest
Nothing has changed.
Graph produced from my code run with updated mplib
Graph produced from #Engineero 's code run with updated mplib
Try using axis.set_yscale with axis.tick_params. Something like:
fig = plt.figure(2)
axis = fig.add_subplot(111)
axis.plot(data2[0, :, 0], sli)
axis.set_yscale('log', nonposy='clip')
axis.tick_params(axis='y', which='minor', colors='black')
axis.set_xlabel('n-value')
axis.set_ylabel('Intensity')
axis.set_title('Intensity vs. n-shell')
plt.show()
Basically use the axis API. This is the only way I was ever able to get minor log-scale tick marks to work for me the way that I wanted...

Matplotlib: change position of plot

I did the following plot with the figure size (which should not be changed):
plt.figure(figsize=(14, 5))
Unfortunately, the x-label is not fully visible. My question: Is it possible, to move the whole grafic to the top (because there would be enough space)?
The code:
plt.figure(figsize=(14, 5))
plt.plot(time_load,load, linewidth=1.5)
plt.grid(True)
plt.tick_params(labelsize=16)
plt.xlabel('Time [hours]',fontsize=16)
plt.xlim([0,24])
plt.xticks([0,4,8,12,16,20,24])
plt.legend(loc="upper left",fontsize = 'large')
Thank you very much for your help!
You can also try
plt.subplots_adjust(bottom=0.19)
If 0.19 adds too much or too little space to see the x-label better, then try adjusting little by little up or down.
A very simple approach is to use
plt.tight_layout()
See: http://matplotlib.org/users/tight_layout_guide.html
Thank you very much for your help!
You can use the axes() command that allows you to specify the location as axes. You can also use the xlim() command and ylim() command. In your case, you can use the latter. So just as an example, the xlim method can be used like this:
plt.xlim(X.min()*1.1, X.max()*1.1)
plt.ylim(C.min()*1.1, C.max()*1.1)
This will make some space for the data points to be seen clearly. Hope that helps.
Just seen the code so you're using xlim method. You want to create the subplot somewhere else, for that you can use the axis() method.
plt.axes([0.3, 0.3, .5, .5])
You can adjust plot accordingly. This one will create a subplot in the upper right corner of the figure.

python 2D grid plot with origin at left upper corner [duplicate]

How can I flip the origin of a matplotlib plot to be in the upper-left corner - as opposed to the default lower-left? I'm using matplotlib.pylab.plot to produce the plot (though if there is another plotting routine that is more flexible, please let me know).
I'm looking for the equivalent of the matlab command: axis ij;
Also, I've spent a couple hours surfing matplotlib help and google but haven't come up with an answer. Some info on where I could have looked up the answer would be helpful as well.
The easiest way is to use:
plt.gca().invert_yaxis()
After you plotted the image. Origin works only for imshow.
axis ij just makes the y-axis increase downward instead of upward, right? If so, then matplotlib.axes.invert_yaxis() might be all you need -- but I can't test that right now.
If that doesn't work, I found a mailing post suggesting that
setp(gca(), 'ylim', reversed(getp(gca(), 'ylim')))
might do what you want to resemble axis ij.
For an image or contour plot, you can use the keyword origin = None | 'lower' | 'upper' and for a line plot, you can set the ylimits high to low.
from pylab import *
A = arange(25)/25.
A = A.reshape((5,5))
figure()
imshow(A, interpolation='nearest', origin='lower')
figure()
imshow(A, interpolation='nearest')
d = arange(5)
figure()
plot(d)
ylim(5, 0)
show()
The following is a basic way to achieve this
ax=pylab.gca()
ax.set_ylim(ax.get_ylim()[::-1])
This
plt.ylim(max(plt.ylim()), min(plt.ylim()))
has an advantage over this
plt.gca().invert_yaxis()
and is that if you are in interactive mode and you repeatedly plot the same plot (maybe with updated data and having a breakpoint after the plot) the y axis won't keep inverting every time.

Changing tick label line spacing in matplotlib

I have a quite cluttered plot with y-ticklabels that need to be very long. I've resorted into wrapping them into multiline text with textwrap. However that makes the labels overlap (or at least come too close), between categories.
I can't solve it by spacing the ticks, making the graph larger, changing font or making the text smaller. (I've already pushed these limits)
As I see it, I could resolve and make it work if I could adjust the line spacing/height to be less than what the font requests.
So imagine for simplicity's sake the following tick-label desperately needs shorter line distance between lines/line height:
from matplotlib import pyplot as plt
plt.barh(0.75, 10, height=0.5)
plt.ylim(0, 2)
plt.yticks([1], ["A very long label\nbroken into 2 line"])
plt.subplots_adjust(left=0.3)
plt.show()
I've checked plt.tick_params() the rcParams without finding any obvious solution. I'm using latex to format the text, but trying to use \hspace(0.5em} in the tick label string seemed not to work/only make things worse.
Any suggestion as to how the line spacing can be decreased would be much appreciated.
You can use the linespacing keyword in your plt.yticks line. For example:
plt.yticks([1], ["A very long label\nbroken into 2 line"],linespacing=0.5)
You can play with the exact value of linespacing to fit your needs. Hope that helps.
Here's the original output of your code:
And here it is with a linespacing of 0.5:
Attempt using this:
pylab.rcParams['xtick.major.pad']='???'
Mess around with the ??? value to get something you like. You could also try (sing the OO interface):
fig = plt.figure()
ax = fig.add_subplot(111)
ax.tick_params(axis='both', which='major', labelsize=8)
ax.set_yticks([1], ["A very long label\nbroken into 2 line"], linespacing=0.5)
plt.show()
The labelsize command will change the size of your font.
Use a combination of the above with the rcparams setup.

zorder value to force grid to background [duplicate]

In Matplotlib, I make dashed grid lines as follows:
fig = pylab.figure()
ax = fig.add_subplot(1,1,1)
ax.yaxis.grid(color='gray', linestyle='dashed')
however, I can't find out how (or even if it is possible) to make the grid lines be drawn behind other graph elements, such as bars. Changing the order of adding the grid versus adding other elements makes no difference.
Is it possible to make it so that the grid lines appear behind everything else?
According to this - http://matplotlib.1069221.n5.nabble.com/axis-elements-and-zorder-td5346.html - you can use Axis.set_axisbelow(True)
(I am currently installing matplotlib for the first time, so have no idea if that's correct - I just found it by googling "matplotlib z order grid" - "z order" is typically used to describe this kind of thing (z being the axis "out of the page"))
To me, it was unclear how to apply andrew cooke's answer, so this is a complete solution based on that:
ax.set_axisbelow(True)
ax.yaxis.grid(color='gray', linestyle='dashed')
If you want to validate the setting for all figures, you may set
plt.rc('axes', axisbelow=True)
or
plt.rcParams['axes.axisbelow'] = True
It works for Matplotlib>=2.0.
I had the same problem and the following worked:
[line.set_zorder(3) for line in ax.lines]
fig.show() # to update
Increase 3to a higher value if it does not work.
You can also set the zorder kwarg in matplotlib.pyplot.grid
plt.grid(which='major', axis='y', zorder=-1.0)
You can try to use one of Seaborn's styles. For instance:
import seaborn as sns
sns.set_style("whitegrid")
Not only the gridlines will get behind but the looks are nicer.
For some (like me) it might be interesting to draw the grid behind only "some" of the other elements. For granular control of the draw order, you can use matplotlib.artist.Artist.set_zorder on the axes directly:
ax.yaxis.grid(color='gray', linestyle='dashed')
ax.set_zorder(3)
This is mentioned in the notes on matplotlib.axes.Axes.grid.

Categories