GKB
GKB

Reputation: 1

time as x-axis for non-continuous time (as cftime.DatetimeProlepticGregorian)

I need to plot just year on x-axis. My time array looks like

array([cftime.DatetimeProlepticGregorian(2002, 8, 1, 0, 0, 0, 0, has_year_zero=True),
       cftime.DatetimeProlepticGregorian(2002, 8, 2, 0, 0, 0, 0, has_year_zero=True),
       cftime.DatetimeProlepticGregorian(2002, 8, 3, 0, 0, 0, 0, has_year_zero=True),
       ...,
       cftime.DatetimeProlepticGregorian(2022, 10, 29, 0, 0, 0, 0, has_year_zero=True),
       cftime.DatetimeProlepticGregorian(2022, 10, 30, 0, 0, 0, 0, has_year_zero=True),
       cftime.DatetimeProlepticGregorian(2022, 10, 31, 0, 0, 0, 0, has_year_zero=True)],
      dtype=object)

When I plot:

df = pd.DataFrame({"Date": date_time.astype(str),
                   "Value": values})
fig, ax = plt.subplots(1,1,figsize=(15,3))
#df.Date.astype(str)
plt.set_loglevel('WARNING')
ax.plot(df.Date, df.Value, linestyle='dotted')
ax.xaxis.set_major_locator(YearLocator(1, month=1, day=5))  # Tick locator #, day=10

I get 1

But, I just want years on x-axis.

What I tried was, converting the datetime to pandas index, then to numeric

year = pd.DatetimeIndex(date_time).year
dt = pd.to_numeric(year)

and I get

enter image description here

This happening because, my data uses only 3 months as a continuous array and not the entire year, but I wanted those 3 months to look continuous annually. That is, as the data is non-continuous I can't set/use the pd.date_range(start = '2002-08-01', end = '2022-08-23', freq = 'D'), the length of the array changes to 7397, whereas mine is 1900 (As it uses only 3 months data). How can I customize the pandas time-index to just Aug-Sep-Oct and loop over to get a continuous array plot?

Altogether, I wanted the plot to look like a daily one in the top image whilst having the x-axis as only years, so that it can accommodate more years to visualize.

Any help will be highly appreciated Many thanks

Update 1 :::: After doing what @matt suggested, it answers the year on x-axis but as the data has breaks and uses only few months the image looks like 3

Upvotes: 0

Views: 167

Answers (1)

Matt Pitkin
Matt Pitkin

Reputation: 6417

As in, e.g., this answer, I think all you need to change is to switch

ax.xaxis.set_major_locator(YearLocator(1, month=1, day=5))

to be:

from matplotlib.dates import YearLocator, DateFormatter

...

ax.xaxis.set_major_locator(YearLocator(1))
ax.xaxis.set_major_formatter(DateFormatter("%Y"))

i.e., just specify the year locator to be every year and the formatting of the date to only show the year.

Update:

If there's a problem of the date's starting at 1970 in the plot, then you can wrap the date_time.astype(str) in a pd.to_datetime(), e.g.,

df = pd.DataFrame(
    {
        "Date": pd.to_datetime(date_time.astype(str)),
        "Value": values,
    }
)

Upvotes: 0

Related Questions