0

Good day,

I would like to dynamically locate my ticks and showing the min and max of the data (which is varying, thus I really can't harcode the conditions). I'm trying to use matplotlib.ticker functions and the best that I can find is MaxNLocator().. but unfortunately, it does not consider the limits of my dataset.

What would be the best approach to my problem?

Thanks!

pseudocode as follows:

import matplotlib.pyplot as plt
from matplotlib.ticker import MaxNLocator


data1 = range(5)
ax1 = plt.subplot(2,1,1)
ax1.plot(data1)

data2 = range(63)
ax2 = plt.subplot(2,1,2)
ax2.plot(data2)

ax1.xaxis.set_major_locator(MaxNLocator(integer=True))
ax2.xaxis.set_major_locator(MaxNLocator(integer=True))

plt.show()

and the output is:

Matplotlib ticks and data limits

c4mm11
  • 49
  • 2
  • 8
  • plt.xlim( (xmin, xmax) ) – Kinght 金 Oct 30 '17 at 09:40
  • https://stackoverflow.com/questions/15858192/how-to-set-xlim-and-ylim-for-a-subplot-in-matplotlib – Kinght 金 Oct 30 '17 at 09:41
  • @Silencer I don't think that's quite what the OP is asking. I think they want ticks located from 0 to 63 (in this case) but in the example the ticks go from 0 to 64. Changing the limits in this example doesn't change the tick location – DavidG Oct 30 '17 at 09:44
  • Nope, it just removes the trailing ticks on the side, but still does not reflect the limits on the ticks. Thanks tho. – c4mm11 Oct 30 '17 at 09:45
  • I don't understand with the downvote. If you have concerns, please address it rather than clicking the downvote. Let's be constructive :/ – c4mm11 Oct 30 '17 at 13:42
  • A band-aid solution that I did is that I'll `xticks = get_xticks()`, `xticks[-2] = vmax`. It's not as robust but that'll do. I do hope there's other better solutions. – c4mm11 Oct 30 '17 at 13:44

1 Answers1

1

Not sure about best approach, but one possible way to do this would be to create a list of numbers between your minimum and maximum using numpy.linspace(start, stop, num). The third argument passed to this lets you control the number of points generated. You can then round these numbers using a list comprehension, and then set the ticks using ax.set_xticks().

Note: This will produce unevenly distributed ticks in some cases, which may be unavoidable in your case

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

data1 = range(5)
ax1 = plt.subplot(2,1,1)
ax1.plot(data1)

data2 = range(63)  # max of this is 62, not 63 as in the question
ax2 = plt.subplot(2,1,2)
ax2.plot(data2)

ticks1 = np.linspace(min(data1),max(data1),5)
ticks2 = np.linspace(min(data2),max(data2),5)

int_ticks1 = [round(i) for i in ticks1]
int_ticks2 = [round(i) for i in ticks2]

ax1.set_xticks(int_ticks1)
ax2.set_xticks(int_ticks2)

plt.show()

This gives:

enter image description here

Update: This will give a maximum numbers of ticks of 5, however if the data goes from say range(3) then the number of ticks will be less. I have updates the creating of int_ticks1 and int_ticks2 so that only unique values will be used to avoid repeated plotting of certain ticks if the range is small

Using the following data

data1 = range(3)
data2 = range(3063)

# below removes any duplicate ticks
int_ticks1 = list(set([int(round(i)) for i in ticks1]))
int_ticks2 = list(set([int(round(i)) for i in ticks2]))

This produces the following figure:

enter image description here

DavidG
  • 24,279
  • 14
  • 89
  • 82
  • Hi! Thanks for the answer, but I really can't hardcode the conditions (5 ticks for data1 and 10 ticks for data 2) as the data is really varying. The plotting is enclosed in a function, so every data uses the same plotting function. – c4mm11 Oct 30 '17 at 10:10
  • Do you want a constant number of ticks all the time then? – DavidG Oct 30 '17 at 10:13
  • No, the data is sometimes only less than 5, but sometimes also larger than 50. So number of ticks couldn't be constant. – c4mm11 Oct 30 '17 at 10:28
  • 1
    @c4mm11 So putting for example 5 in `np.linspace` creates a maximum of 5 ticks. If your data range is small then it will create less than 5 (providing the duplicate ticks are removed). I have updated my answer with a few additions. – DavidG Oct 30 '17 at 10:39
  • Oh, I forgot about the `set`. The solution works but produces uneven ticks. Sadly, the visual is very important in my output. I'm really grateful for the effort. – c4mm11 Oct 30 '17 at 11:13
  • You won't be able to get evenly spaced ticks from 0 - 62 that include 0 and 62... – DavidG Oct 30 '17 at 11:33