2

I am trying to lower the frequency of the xticks so that its more readable, but I am not able to do so when the x ticks are not integers. Please see example below (matplotlib 2.1.1):

f = plt.figure(figsize=(5, 5))
ax1 = f.add_subplot(211)
ax2 = f.add_subplot(212)

x = [1,2,3,4,5,6,7]
y = [13,15,17,14,17,20,21]

ax1.plot(x, y, label="test1")
ax2.plot(x, y, label="test2")

ax2.set_xticks(ax2.get_xticks()[::2])

plt.subplots_adjust(hspace=1)
plt.show()

enter image description here

This example works perfectly fine that the second graph now displays the x ticks every 2 tick.

When I change the x values to non integers like so

f = plt.figure(figsize=(5, 5))
ax1 = f.add_subplot(211)
ax2 = f.add_subplot(212)

x = ["10:31","10:32","10:33","10:34","10:35","10:36","10:37"]
y = [13,15,17,14,17,20,21]

ax1.plot(x, y, label="test1")
ax2.plot(x, y, label="test2")

ax2.set_xticks(ax2.get_xticks()[::2])

plt.subplots_adjust(hspace=1)
plt.show()

Then the graph is no longer accurate. The spacing of the tick is now every 2, but it is still incrementing by 1 and is now not aligned correctly with the data.

enter image description here

Zephyr
  • 11,891
  • 53
  • 45
  • 80
user1179317
  • 2,693
  • 3
  • 34
  • 62
  • I run your code and got the plot with ticks correctly aligned: [plot](https://i.stack.imgur.com/Rz9Rj.png) (using matplotlib 3.4.2 and python 3.9.6) – Zephyr Aug 11 '21 at 20:43
  • 1
    hmm yea I am using matplotlib 2.1.1 and I cant currently update our environment – user1179317 Aug 11 '21 at 20:49

1 Answers1

2

This issue is solved with a more recent version of matplotlib. Your code in matplotlib 3.4.2 works fine.


If you cannot update your environment, you should treat x axis format as datetime (tested with matplotlib 2.1.1).
In order to do this, first of all you have to convert x axis from str to datetime:

x_time = [datetime.strptime(x_i, '%H:%M') for x_i in x]

Then you plot your data replacing x with x_time:

ax2.plot(x_time, y, label="test2")

Now matplotlib knows your x axis is a datetime format. You still need to format properly ticks:

ax2.xaxis.set_major_locator(md.MinuteLocator(interval = 1))
ax2.xaxis.set_major_formatter(md.DateFormatter('%H:%M'))

MinuteLocator places ticks each interval value (1 minute in this case) and DateFormatter formats ticks in '%H:%M' format.
Finally you can set the space between each tick with:

ax2.set_xticks(ax2.get_xticks()[::2])

enter image description here

You could also avoid the last line and control space between ticks with interval parameter:

ax2.xaxis.set_major_locator(md.MinuteLocator(interval = 2))

enter image description here

Complete Code

import matplotlib.pyplot as plt
from datetime import datetime
import matplotlib.dates as md

f = plt.figure(figsize=(5, 5))
ax1 = f.add_subplot(211)
ax2 = f.add_subplot(212)

x = ["10:31","10:32","10:33","10:34","10:35","10:36","10:37"]
y = [13,15,17,14,17,20,21]

x_time = [datetime.strptime(x_i, '%H:%M') for x_i in x]

ax1.plot(x, y, label="test1")
ax2.plot(x_time, y, label="test2")

ax2.xaxis.set_major_locator(md.MinuteLocator(interval = 1))
ax2.xaxis.set_major_formatter(md.DateFormatter('%H:%M'))

ax2.set_xticks(ax2.get_xticks()[::2])

plt.subplots_adjust(hspace=1)
plt.show()
Zephyr
  • 11,891
  • 53
  • 45
  • 80