Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Center x-axis labels in line plot

I am building a line plot with two lines, one for high temperatures and the other for low temperatures. The x-axis is based on days over one complete year in datetime format (2014-01-01, etc.). However, I changed the labels–not the data–for months (Jan, Feb, Mar, etc). The problem is that the first label 'Jan' is in the origin. What I want is to move all labels to the right to center them between ticks.

fig, ax = plt.subplots()

plt.plot(x, y1)
plt.plot(x, y2)

# Change x-axis from %y-%m-%d format to %m:
monthsFmt = mdates.DateFormatter('%m')
plt.gca().xaxis.set_major_formatter(monthsFmt)

# Replace numeric x-axis labels (1,2,3, ..., 12) for abbreviations of months ('Jan', 'Feb', 'Mar', etc.):
labels = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
ax.set_xticklabels(labels)

# CODE GOES HERE TO CENTER X-AXIS LABELS...

# Render plot:
plt.show()

This is the result that I am looking for:

enter image description here

like image 261
Antonio Serrano Avatar asked Apr 03 '17 14:04

Antonio Serrano


1 Answers

Using the minor ticks as suggested in the thread posted by DavidG should work. Below is a MWE that I've adapted for your specific problem, forcing the major ticks to appear on the first of each month and using the minor ticks to place the labels in-between the major ticks :

import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
import datetime

# Generate some data for example :

yr = 2014
fig, ax = plt.subplots()

x0 = datetime.datetime(yr, 1, 1)
x = np.array([x0 + datetime.timedelta(days=i) for i in range(365)])

y1 = np.sin(2*np.pi*np.arange(365)/365) + np.random.rand(365)/5
y2 = np.sin(2*np.pi*np.arange(365)/365) + np.random.rand(365)/5 - 1

# Draw high and low temperatures lines :

ax.plot(x, y1, color='#c83c34')
ax.plot(x, y2, color='#28659c')
ax.fill_between(x, y2, y1, facecolor='#daecfd', alpha=0.5)

# Force the major ticks position on the first of each month and hide labels:

xticks = [datetime.datetime(yr, i+1, 1) for i in range(12)]
xticks.append(datetime.datetime(yr+1, 1, 1))
ax.set_xticks(xticks)
ax.tick_params(axis='both', direction='out', top=False, right=False)
ax.axis([xticks[0], xticks[-1], -2.5, 1.5])
ax.set_xticklabels([])

# CODE GOES HERE TO CENTER X-AXIS LABELS...

labels = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
          'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
mticks = ax.get_xticks()
ax.set_xticks((mticks[:-1]+mticks[1:])/2, minor=True)
ax.tick_params(axis='x', which='minor', length=0)
ax.set_xticklabels(labels, minor=True)
fig.tight_layout()

plt.show()

which results in: enter image description here

like image 62
Jean-Sébastien Avatar answered Sep 30 '22 07:09

Jean-Sébastien