Bart
Bart

Reputation: 10268

`set_major_locator` removes x-ticks (and labels) from previous subplots?

I ran into this strange problem with using set_major_locator(), when using subplots which have different x-axis limits. A minimal example:

import matplotlib.pyplot as pl
import matplotlib.dates as mdates
from datetime import datetime

h24 = mdates.HourLocator(interval=24)
fmt = mdates.DateFormatter('%d-%m %H:%M')

start1 = datetime(year=2016, month=7, day=7, hour=0)
end1   = datetime(year=2016, month=7, day=9, hour=0)

start2 = datetime(year=2016, month=9, day=30, hour=0)
end2   = datetime(year=2016, month=10, day=2, hour=0)

start3 = datetime(year=2016, month=5, day=8,  hour=0)
end3   = datetime(year=2016, month=5, day=10, hour=0)

pl.figure(figsize=(9,3))

ax=pl.subplot(131)
ax.set_xlim(start1, end1)
ax.xaxis.set_major_locator(h24)
ax.xaxis.set_major_formatter(fmt)

ax=pl.subplot(132)
ax.set_xlim(start2, end2)
ax.xaxis.set_major_locator(h24)
ax.xaxis.set_major_formatter(fmt)

ax=pl.subplot(133)
ax.set_xlim(start3, end3)
ax.xaxis.set_major_locator(h24)
ax.xaxis.set_major_formatter(fmt)

pl.tight_layout()

Which results in:

enter image description here

If I set the x-limit of all sub-plots the same (using in this case ax.set_xlim(start1, end1) for all sub-plots) it works as expected:

enter image description here

Also, leaving the different set_xlim()'s and removing the set_major_locator() and set_major_formatter() lines works (although I get unreadable x-labels in this case..):

enter image description here

Am I making a silly mistake somewhere, or are the missing x-ticks and labels in my first example a bug in Matplotlib?

p.s. Matplotlib 3.0.2, Python 3.7.2

Upvotes: 1

Views: 2803

Answers (1)

ImportanceOfBeingErnest
ImportanceOfBeingErnest

Reputation: 339350

As of current versions of matplotlib you cannot reuse the same ticker and formatter for dates on several axes. So you need one locator and one formatter per axes.

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


def fmt_xaxes(ax):
    h24 = mdates.HourLocator(interval=24)
    fmt = mdates.DateFormatter('%d-%m %H:%M')
    ax.xaxis.set_major_locator(h24)
    ax.xaxis.set_major_formatter(fmt)


start1 = datetime(year=2016, month=7, day=7, hour=0)
end1   = datetime(year=2016, month=7, day=9, hour=0)

start2 = datetime(year=2016, month=9, day=30, hour=0)
end2   = datetime(year=2016, month=10, day=2, hour=0)

start3 = datetime(year=2016, month=5, day=8,  hour=0)
end3   = datetime(year=2016, month=5, day=10, hour=0)


fig, (ax1, ax2, ax3) = plt.subplots(ncols=3, figsize=(9,3))


ax1.set_xlim(start1, end1)
fmt_xaxes(ax1)

ax2.set_xlim(start2, end2)
fmt_xaxes(ax2)

ax3.set_xlim(start3, end3)
fmt_xaxes(ax3)

plt.tight_layout()
plt.show()

Upvotes: 4

Related Questions