force matplotlib to show only positive numbers starting from 0 on the Y axis

10,241

Solution 1

ax.set_ylim is the method which changes the limits on the y-axis of the subplot. In order to use this, you must have at your disposal an Axes instance (the one that is returned by plt.subplot); then you can set the lower limit to 0. Something along these lines should work:

ax = plt.subplot(1, 1, 1)
ax.plot(x, y)
ax.set_ylim(bottom=0.)
plt.show()

To change the tick label format, one convenient way is to use FormatStrFormatter:

from matplotlib.ticker import FormatStrFormatter
ax.yaxis.set_major_formatter(FormatStrFormatter('%.1f'))

EDIT: I've looked at your code; you can get an Axes instance with fig.gca() method, then setting ylim and major_formatter as described above.

EDIT2: The problem addressed it the comment can be solved by specifying the ticks locator. The locator used by default is AutoLocator, which is essentially the MaxNLocator with default values. One of the keywords taken by MaxNLocator is integer, which specifies only integer values for ticks and is False by default. Thus, to make ticks take only integer values, you need to define for y-axis MaxNLocator with integer=True. This should work:

from matplotlib.ticker import MaxNLocator
ax.yaxis.set_major_locator(MaxNLocator(integer=True))

EDIT3:

And if you want to set your top y limit to 10, you should explicitly set it to 10:

if ymax < 10:
    axis_data.set_ylim(bottom=0., top=10.)
else:
    axis_data.set_ylim(bottom=0.)

Solution 2

The axis range can be limited to a particular range by xlim() or ylim(), e.g.

ylim([0,2])

and the axis ticks can be set manually to any string using xticks() or yticks(), e.g.

yticks([0,1,2],["0","1","2"])

Solution 3

Unfortunately there are many ways to adjust the ticks. So it can sometimes become a mess.

Try:

tickpos = [1,2,5]

py.axis(ymin = 0)
py.yticks(tickpos,tickpos)

If you don't use tickpos in both arguments and use two different arrays, the first array says where the ticks are. The second says what the tick labels are. This is useful if maybe you want the label to be a string (say it's a bar chart and you want the label to be category for the given bar). It's very dangerous if you have them as numbers because you may find that you move the tick location, but not the label. So you're labeling location y=4 as, say, 6. The following would be BAD

py.yticks([1,2,3], [1, 4, -1])  #DO NOT DO THIS

You can also set py.axis(ymin = 0, ymax = 4, xmin = 3) or other variants depending on what limits you want py to be free to set. As a note, sometimes I set ymax = 4.000001 if I want to be sure that the tick at y=4 appears.

Share:
10,241
yoshiserry
Author by

yoshiserry

Updated on July 12, 2022

Comments

  • yoshiserry
    yoshiserry almost 2 years

    In a loop I have created some subplots using Matplotlib.

    I noticed that in some instances the Y axis (particularly when displaying 0's) shows some negative numbers on the Y axis.

    Is there a parameter to force the Y axis to display Positive numbers (i.e. from 0 upwards.

    And a parameter to make the Y axis values either one or no decimal places. (display 2 instead of 2.0 or 2.00 (which it seems to do automatically depending on the data).

    code:

    for a in account_list:
        f = plt.figure()
        f.set_figheight(20)
        f.set_figwidth(20)
        f.sharex = True
        f.sharey=True
    
        left  = 0.125  # the left side of the subplots of the figure
        right = 0.9    # the right side of the subplots of the figure
        bottom = 0.1   # the bottom of the subplots of the figure
        top = 0.9      # the top of the subplots of the figure
        wspace = 0.2   # the amount of width reserved for blank space between subplots
        hspace = .8  # the amount of height reserved for white space between subplots
        subplots_adjust(left=left, right=right, bottom=bottom, top=top, wspace=wspace, hspace=hspace)
    
        count = 1
        for h in headings:
            sorted_data[sorted_data.account == a].ix[0:,['month_date',h]].plot(ax=f.add_subplot(7,3,count),legend=True,subplots=True,x='month_date',y=h)
    
            import matplotlib.patches as mpatches
            legend_name = mpatches.Patch(color='none', label=h)
            plt.xlabel("")
            ppl.legend(handles=[legend_name],bbox_to_anchor=(0.,1.2,1.0,.10), loc="center",ncol=2, mode="expand", borderaxespad=0.)
            count = count + 1
    

    enter image description here

    EDIT

    When I set the minimum and maximum for the Y axis using the below: I end up with the numbers repeating. For instance where the plot used to have on the Y axis: 1, 1.5, 2, 2.5 it now just has 1, 1, 2, 2, 3, 3, (I want each number to only appear once.

    Maybe it has to do with the fact that my if statement is not working. I want all plots with a maximum Y axis value lower than ten to have their maximum Y value set to ten.

    #set bottom Y axis limit to 0 and change number format to 1 dec place.
        axis_data = f.gca()
    
        from matplotlib.ticker import FormatStrFormatter
        axis_data.yaxis.set_major_formatter(FormatStrFormatter('%.0f'))
    
        #set only integers on Y axis >>>
        import matplotlib.ticker as ticker
        axis_data.xaxis.set_major_locator(ticker.MaxNLocator(integer=True))
    
        #if y max < 10 make it ten
        ymin,ymax = axis_data.get_ylim()
        print(type(ymax))
    
        if ymax <10:
            axis_data.set_ylim(bottom=0.,top=ymax)
        else:
            axis_data.set_ylim(bottom=0.)
    

    enter image description here