Python Forum
Floor division problem with plotting x-axis tick labels
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Floor division problem with plotting x-axis tick labels
#1
Because of the issue I posted about a couple weeks (?) ago regarding matplotlib's asymmetric plotting of x-axis labels (for me, they were at locations of the 1st and 22nd of each month), I'm trying a different approach. Here's some code:

import matplotlib

a = ['2017-01-06', '2017-01-13', '2017-01-20', '2017-01-27', '2017-02-03', '2017-02-10', '2017-02-17', \
     '2017-02-24', '2017-03-03', '2017-03-10', '2017-03-17', '2017-03-24', '2017-03-31', '2017-04-07', \
     '2017-04-14', '2017-04-21', '2017-04-28', '2017-05-05', '2017-05-12', '2017-05-19']
b = [433, 1216, 1234, 2175, 2825, 3271, 3240, 2979, 2234, 3114, 3139, 2975, 3831, 3758, 4127, 4900, 4216,\
     4785, 4043, 4346]
fig, ax = plt.subplots(1)
ax.plot(a,b) 
ax.xaxis.set_major_locator(matplotlib.ticker.FixedLocator([x for x in range(len(a)) if x%(len(a)//3)== 0]))
plt.xticks(rotation=90) 
plt.show()
What I'm trying to get is n tick labels where n is the divisor as shown in the L10 list comprehension.

len(a) = 20. If I want 3 total tick labels then I divide 20 / 3 = 6.67, round that down to 6, and count every sixth week including the first: 2017-01-06, 2017-2-17, 2017-3-31, 2017-5-12. Whoops, that's four tick labels not three! This is exactly what I get, too. //4 plots 4 tick labels and //5 plots 5 tick labels as I'd like. //6 gives 7 tick labels, though.

I suspect the problem here is with the floor division operation, but I need to have an integer divisor for %.

The following works for 1-5 but dividing by 6 or 7 both plot 7 tick labels::

ax.xaxis.set_major_locator(matplotlib.ticker.FixedLocator([x for x in range(len(a)) if x%(round(len(a)/6,0))== 0]))
Can you articulate what I'm overlooking in my logic? Thanks!
Reply
#2
Between n+1 dates, there are n intervals of dates. I suggest to take (len(a) - 1)//(n - 1). For example
>>> (20-1)//(3-1)
9
this would take a[0], a[9], a[18]
Reply
#3
If I want to see n tick labels, this doesn't work for n = 6:

ax.xaxis.set_major_locator(matplotlib.ticker.FixedLocator([x for x in range(len(a)) if x%((len(a)-1)//(6-1))== 0]))
This results in seven tick labels.

Thinking out loud, x will count from 0 to 19 starting at 0. 0%anything == 0 so we get the first tick label. Then we get no remainder when x = 3, 6, 9, 12, 15, and 18 (since 18 // 5 == 3), which is seven tick labels total.
Reply
#4
The following code shows that for evenly spaced tick labels having integer coordinates, only certain numbers of tick labels are possible. For example it is impossible to have 6 or 8 evenly spaced tick labels
>>> for k in range(1, 20):
...     L = list(range(0, 20, k))
...     print(len(L), L)
... 
20 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
10 [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
7 [0, 3, 6, 9, 12, 15, 18]
5 [0, 4, 8, 12, 16]
4 [0, 5, 10, 15]
4 [0, 6, 12, 18]
3 [0, 7, 14]
3 [0, 8, 16]
3 [0, 9, 18]
2 [0, 10]
2 [0, 11]
2 [0, 12]
2 [0, 13]
2 [0, 14]
2 [0, 15]
2 [0, 16]
2 [0, 17]
2 [0, 18]
2 [0, 19]

Why not use numpy.linspace to get a sequence of evenly spaced real numbers having a given length?
>>> np.linspace(0, 20, 6)
array([ 0.,  4.,  8., 12., 16., 20.])
>>> np.linspace(0, 19, 6)
array([ 0. ,  3.8,  7.6, 11.4, 15.2, 19. ])
Reply
#5
(Mar-30-2022, 06:41 PM)Gribouillis Wrote: The following code shows that for evenly spaced tick labels having integer coordinates, only certain numbers of tick labels are possible. For example it is impossible to have 6 or 8 evenly spaced tick labels
That's good stuff. There is no 6, for example, and I get 7 instead.

So I have done a poor job articulating what I want. I have in my head what I want to see and I haven't expressed it well in words or in the flawed code I proposed. What I was hoping for was constant spacing with the final number being the lowest possible. So for 2 tick labels, I want [0,10]. For 3 tick labels, I want [0,7,14]. For 4 tick labels, I want [0, 5, 10, 15]. For 5 tick labels it has to be [0, 4, 8, 12, 16]. For 6 there is none and that's why it doesn't work.

So I'll stop banging myself over the head for being dumb on this. This is a nifty three lines of code you put together that nicely shows the possibilities. Thanks!

(Mar-30-2022, 06:48 PM)Gribouillis Wrote: Why not use numpy.linspace to get a sequence of evenly spaced real numbers having a given length?
I like that better! This is outstanding to see the differences:

import matplotlib

a = ['2017-01-06', '2017-01-13', '2017-01-20', '2017-01-27', '2017-02-03', '2017-02-10', '2017-02-17', \
     '2017-02-24', '2017-03-03', '2017-03-10', '2017-03-17', '2017-03-24', '2017-03-31', '2017-04-07', \
     '2017-04-14', '2017-04-21', '2017-04-28', '2017-05-05', '2017-05-12', '2017-05-19']
b = [433, 1216, 1234, 2175, 2825, 3271, 3240, 2979, 2234, 3114, 3139, 2975, 3831, 3758, 4127, 4900, 4216,\
     4785, 4043, 4346]
fig, axs = plt.subplots(20, figsize=(15, 120)) #second arg of figsize allows this to be tall enough for all subplots

for i in range(20):
    plt.sca(axs[i]) #this allows plt.xticks to be applied to every subplot
    axs[i].plot(a,b) 
    axs[i].xaxis.set_major_locator(matplotlib.ticker.FixedLocator(np.linspace(0,19,i)))
    plt.xticks(rotation=90) 
plt.tight_layout()
plt.show()
Reply
#6
(I'm going to move this to a new thread because it's no longer about floor division anymore)
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
Question Why was floor division used here? tmv 2 114 Jan-31-2026, 02:00 AM
Last Post: Pedroski55
  Division Mallard 9 890 Dec-17-2025, 03:47 PM
Last Post: Mallard
  division error nathanael 2 776 Dec-12-2025, 11:55 PM
Last Post: deanhystad
  Get numpy ceil and floor value for nearest two decimals klllmmm 4 4,895 Jun-07-2023, 07:35 AM
Last Post: paul18fr
  Division questions Dionysis 5 3,605 Feb-14-2023, 02:02 PM
Last Post: Dionysis
  Floor approximation problem in algorithm gradlon93 3 2,329 Dec-14-2022, 07:48 PM
Last Post: Gribouillis
  How can histogram bins be separated and reduce number of labels printed on x-axis? cadena 1 2,636 Sep-07-2022, 09:47 AM
Last Post: Larz60+
  Division by zero and value of argument Lawu 5 10,682 Jul-01-2022, 02:28 PM
Last Post: Lawu
  Points not plotting with reference to x-tick labels Mark17 2 2,619 Jun-14-2022, 05:38 PM
Last Post: Mark17
  How to avoid the extra set of y-axis labels? Mark17 9 8,969 May-17-2022, 06:26 PM
Last Post: Mark17

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020