Plot xtick label with half hour frequency
Question:
I want the X label is like:
00:00 00:30 01:00 01:30 02:00 ...... 23:30
My code:
import matplotlib.pyplot as plt
import pandas as pd
import matplotlib.dates as mdates
import random
data = [random.random() for i in range(48)]
times = pd.date_range('16-09-2017', periods=48, freq='30MIN')
fig, ax = plt.subplots(1)
fig.autofmt_xdate()
plt.plot(times, data)
xfmt = mdates.DateFormatter('%H:%M')
ax.xaxis.set_major_formatter(xfmt)
plt.show()
But my X-Label looks like this:
Whats the problem?
I have 48 values, each value represents a value for a half hour of a day
Answers:
Edit:
As my answer was already accepted but didn’t work correctly, I added simplified solutions for matplotlib and pandas
The key is to set x-ticks
parameter correctly
In your case it could look like this:
data = [random.random() for i in range(48)]
times = pd.date_range('16-09-2017', periods=48, freq='30MIN')
In both cases, you want to use only hours and minutes:
hour_minutes = times.strftime('%H:%M')
1. Matplotlib solution
plt.figure(figsize=(12,5))
plt.plot(range(len(data)),data)
# .plot(times, data)
plt.xticks(range(len(hour_minutes)), hour_minutes, size='small',
rotation=45, horizontalalignment='center')
plt.show()
2. Pandas solution
# create dataframe from arrays (not neccessary, but nice)
df = pd.DataFrame({'values': data,
'hour_minutes': hour_minutes})
# specify size of plot
value_plot = df.plot(figsize=(12,5), title='Value by Half-hours')
# first set number of ticks
value_plot.set_xticks(df.index)
# and label them after
value_plot.set_xticklabels(df.hour_minutes, rotation=45, size='small')
# get the plot figure and save it
fig = value_plot.get_figure()
fig.savefig('value_plot.png')
But I also like the alternative method that is proposed here 🙂
You can use the MinuteLocator
and explicitly set it for every 0 and 30 minutes.
minlocator = mdates.MinuteLocator(byminute=[0,30])
ax.xaxis.set_major_locator(minlocator)
And to clean it up – remove extraneous tick marks and fill out the empty space.
xticks = ax.get_xticks()
ax.set_xticks(xticks[2:-2]);
hh = pd.Timedelta('30min')
ax.set_xlim(times[0] - hh, times[-1] + hh)
I want the X label is like:
00:00 00:30 01:00 01:30 02:00 ...... 23:30
My code:
import matplotlib.pyplot as plt
import pandas as pd
import matplotlib.dates as mdates
import random
data = [random.random() for i in range(48)]
times = pd.date_range('16-09-2017', periods=48, freq='30MIN')
fig, ax = plt.subplots(1)
fig.autofmt_xdate()
plt.plot(times, data)
xfmt = mdates.DateFormatter('%H:%M')
ax.xaxis.set_major_formatter(xfmt)
plt.show()
But my X-Label looks like this:
Whats the problem?
I have 48 values, each value represents a value for a half hour of a day
Edit:
As my answer was already accepted but didn’t work correctly, I added simplified solutions for matplotlib and pandas
The key is to set x-ticks
parameter correctly
In your case it could look like this:
data = [random.random() for i in range(48)]
times = pd.date_range('16-09-2017', periods=48, freq='30MIN')
In both cases, you want to use only hours and minutes:
hour_minutes = times.strftime('%H:%M')
1. Matplotlib solution
plt.figure(figsize=(12,5))
plt.plot(range(len(data)),data)
# .plot(times, data)
plt.xticks(range(len(hour_minutes)), hour_minutes, size='small',
rotation=45, horizontalalignment='center')
plt.show()
2. Pandas solution
# create dataframe from arrays (not neccessary, but nice)
df = pd.DataFrame({'values': data,
'hour_minutes': hour_minutes})
# specify size of plot
value_plot = df.plot(figsize=(12,5), title='Value by Half-hours')
# first set number of ticks
value_plot.set_xticks(df.index)
# and label them after
value_plot.set_xticklabels(df.hour_minutes, rotation=45, size='small')
# get the plot figure and save it
fig = value_plot.get_figure()
fig.savefig('value_plot.png')
But I also like the alternative method that is proposed here 🙂
You can use the MinuteLocator
and explicitly set it for every 0 and 30 minutes.
minlocator = mdates.MinuteLocator(byminute=[0,30])
ax.xaxis.set_major_locator(minlocator)
And to clean it up – remove extraneous tick marks and fill out the empty space.
xticks = ax.get_xticks()
ax.set_xticks(xticks[2:-2]);
hh = pd.Timedelta('30min')
ax.set_xlim(times[0] - hh, times[-1] + hh)