5

I use automatic axes range for data.

For example, when I use x data between -29 and +31 and I do

ax = plt.gca()
xsta, xend = ax.get_xlim()

I get -30 and 40, which does not appropriately describe data range. I would like see that axes ranges are rounded to 5, i.e. -30 and 35 for limits.

Is it possible to do that? Or, alternatively, is it possible to get exact ranges of x-axes data (-29,31) and then write an algorithm to change that manually (using set_xlim)?

Thanks for help.

1
  • use the axis function. Commented Jan 19, 2016 at 18:39

3 Answers 3

12

First off, let's set up a simple example:

import matplotlib.pyplot as plt

fig, ax = plt.subplots()
ax.plot([-29, 31], [-29, 31])
plt.show()

enter image description here

If you'd like to know the data range for manually specifying things as you mentioned, you can use:

ax.xaxis.get_data_interval()
ax.yaxis.get_data_interval()

However, it's very common to want to change to a simple padding of the data limits. In that case, use ax.margins(some_percentage). For example, this would pad the limits with 5% of the data range:

import matplotlib.pyplot as plt

fig, ax = plt.subplots()
ax.plot([-29, 31], [-29, 31])
ax.margins(0.05)
plt.show()

enter image description here

To go back to your original scenario, you could manually make the axes limits only use multiples of 5 (but not change the ticks, etc):

import numpy as np
import matplotlib.pyplot as plt

fig, ax = plt.subplots()
ax.plot([-29, 31], [-29, 31])

multiplier = 5.0
for axis, setter in [(ax.xaxis, ax.set_xlim), (ax.yaxis, ax.set_ylim)]:
    vmin, vmax = axis.get_data_interval()
    vmin = multiplier * np.floor(vmin / multiplier)
    vmax = multiplier * np.ceil(vmax / multiplier)
    setter([vmin, vmax])

plt.show()

enter image description here

We could also accomplish the same thing by subclassing the locator for each axis:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.ticker import AutoLocator

class MyLocator(AutoLocator):
    def view_limits(self, vmin, vmax):
        multiplier = 5.0
        vmin = multiplier * np.floor(vmin / multiplier)
        vmax = multiplier * np.ceil(vmax / multiplier)
        return vmin, vmax

fig, ax = plt.subplots()
ax.plot([-29, 31], [-29, 31])

ax.xaxis.set_major_locator(MyLocator())
ax.yaxis.set_major_locator(MyLocator())
ax.autoscale()

plt.show()
Sign up to request clarification or add additional context in comments.

1 Comment

Yes, get_data_interval is what I was looking for. Thanks!
0

To set the axis xlim to the exact range of the data, use the ax.xlim() method in combination with the built in min() and max() functions:

#x could be a list like [0,3,5,6,15]
ax = plt.gca()
ax.xlim([min(x), max(x)]) # evaluates to ax.xlim([0, 15]) with example data above

Comments

0

When you know you want it in multiples of 5, modify the limits according to the x-range of your data:

import math
import matplotlib.pyplot as pet
#your plotting here
xmin = min( <data_x> )
xmax = max( <data_x> ) 
ax = plt.gca()
ax.set_xlim( [5*math.floor(xmin/5.0), 5*math.ceil(xmax/5.0)]  )

Note that the division has to be by the float 5.0, as int/int neglects the fractional part. For example xmax=6 in 5*math.ceil(6/5) would return 5, which cuts off your data, whereas 5*math.ceil(6/5.0) gives the desired 5*math.ceil(1.2) = 5*2 =10.

1 Comment

Yes I had this idea too, but if you have many plots on the graph that means you have to check each plot separately. I was looking for get_data_interval function.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.