Python Forum

Full Version: How to get evenly-spaced datetime tick labels regardless of x-values of data points?
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
I'm creating a new thread here, which originated in a question about floor division and tick labels. In there, Gribouillis suggested using np.linspace() for the axis. How would I do that with datetimes?

Here's some code:

import pandas as pd
import matplotlib.pyplot as plt

sample_data = [3, 6, 2, 12, 15]
e = pd.date_range('2010-01-01', '2011-12-31',5)
print(e)
print(type(e))
print(list(e))

plt.plot(e,sample_data)
plt.xticks(rotation=90)
plt.show()
I see a few issues here. First, doing this gives me nine x-tick labels from 2010-01 to 2011-01. It doesn't give 5, which is what I wanted (third argument in L5), and the format isn't what I wanted (yyyy-mm-dd as contained in the pd.date_range() line (why?).

Another problem is that if I want more tick labels and change that third argument of pd.date_range() to 15, I get: ValueError: x and y must have same first dimension, but have shapes (15,) and (5,) . That makes sense because I've entered something in the x-coordinate place that doesn't match up with y-coordinates. Really, this date_range is intended to be used only for tick labels that need not correspond with x-coordinates so I probably need to specify a dedicated x-coordinate list for plt.plot() and then create something to be used for [customizable] evenly-spaced datetime tick labels.

Any suggestions as to how I could do this?
(Apr-03-2022, 10:45 PM)Larz60+ Wrote: [ -> ]see: https://matplotlib.org/3.1.1/gallery/tic..._demo.html

How do you suggest I implement that?

I had previously worked successfully with this Class and np.linspace() as the first argument.

This does not work:

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(list(pd.date_range('2010-01-01', '2011-12-31',5))))
plt.xticks(rotation=90) 
plt.show()
With or without that list() constructor, I get TypeError: type Timestamp doesn't define __round__ method
If you look at the documentation for matplotlib.ticker

https://matplotlib.org/stable/api/ticker_api.html

You see this
Quote:There are a number of locators specialized for date locations - see the dates module.
Follow the link:

https://matplotlib.org/stable/api/dates_...tlib.dates
Quote:The available date tickers are:

MicrosecondLocator: Locate microseconds.

SecondLocator: Locate seconds.

MinuteLocator: Locate minutes.

HourLocator: Locate hours.

DayLocator: Locate specified days of the month.

WeekdayLocator: Locate days of the week, e.g., MO, TU.

MonthLocator: Locate months, e.g., 7 for July.

YearLocator: Locate years that are multiples of base.

RRuleLocator: Locate using a matplotlib.dates.rrulewrapper. rrulewrapper is a simple wrapper around dateutil's dateutil.rrule which allow almost arbitrary date tick specifications. See rrule example.

AutoDateLocator: On autoscale, this class picks the best DateLocator (e.g., RRuleLocator) to set the view limits and the tick locations. If called with interval_multiples=True it will make ticks line up with sensible multiples of the tick intervals. E.g. if the interval is 4 hours, it will pick hours 0, 4, 8, etc as ticks. This behaviour is not guaranteed by default.
(Apr-04-2022, 04:33 PM)deanhystad Wrote: [ -> ]If you look at the documentation for matplotlib.ticker

https://matplotlib.org/stable/api/ticker_api.html

You see this
Quote:There are a number of locators specialized for date locations - see the dates module.
Follow the link:

Here's what I ended up with:

import pandas as pd
import matplotlib.pyplot as plt
 
sample_data = [3, 6, 2, 12, 15]
e = pd.date_range('2010-01-01', '2011-12-31',5) #these will be x-coordinates for data
f = pd.date_range('2009-06-30', '2014-12-31',10) #these will be x-axis labels
f = f.strftime('%Y-%m-%d') #reformatted axis labels
 
fig, ax = plt.subplots(1) 
ax.plot(e,sample_data)
ax.set_xticks(f, f, rotation=90) 
plt.show()
That seems to work.

Thanks all!