Home > Blockchain >  Issues plotting every nth date xaxis
Issues plotting every nth date xaxis

Time:11-25

I have a df like this:

     level_0      DATE        ONI  positive  YEAR
686      sst 1960-03-15 -0.364453     False  1960
687      sst 1960-04-15 -0.366851     False  1960
688      sst 1960-05-15 -0.321550     False  1960
689      sst 1960-06-15 -0.382227     False  1960
690      sst 1960-07-15 -0.374074     False  1960
     ...        ...       ...       ...   ...
1363     sst 2016-08-15 -0.597598     False  2016
1364     sst 2016-09-15 -0.784883     False  2016
1365     sst 2016-10-15 -0.900240     False  2016
1366     sst 2016-11-15 -1.006226     False  2016
1367     sst 2016-12-15 -1.065392     False  2016

[682 rows x 5 columns]

I want to plot my data with xaxis every nth year so i did this code:

fig = plt.figure('ONI', figsize=(15,20), dpi=200)
ax = fig.add_axes([0.15,0.15,0.7,0.7])


df_oni.plot(x='DATE',y="ONI",kind='bar', alpha=0.5, color=df_oni.positive.map({True: 'r', False: 'b'}),ax=ax)


date_form = DateFormatter("%Y")
ax.xaxis.set_major_formatter(date_form)
ax.xaxis.set_major_locator(mdates.YearLocator(base=5))

ax.xaxis.set_tick_params(rotation=0)

ax.set_title("Indice ONI",fontsize= 14,fontweight="bold")
# Define the date format

ax.set_ylabel("Valor del Índice\n", fontsize = 10.0)
ax.yaxis.set_major_locator(MaxNLocator(integer=True, min_n_ticks=1))

ax.set_xlabel("")

I don't understand why even with ax.xaxis.set_major_locator(mdates.YearLocator(base=5)) i get this figure with only 1 year in the xaxis:

Would you mind to help me? Thanks in advance.

enter image description here

CodePudding user response:

This is related to the way pandas produces the bar plot where it just indexes the x-position (to verify: ax.get_xlim() gives (-0.5, 681.5)).

The easiest workaround is to use matplotlib directly:

ax.bar(df_oni.DATE,df_oni.ONI, width=20, alpha=0.5, color=df_oni.positive.map({True: 'r', False: 'b'}))

(you'll need to increase the bar width to say 20 for better visual impression)

Example:

import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
import matplotlib.dates as mdates
import matplotlib.ticker as mticker

fig = plt.figure('ONI', figsize=(15,20), dpi=200)
ax = fig.add_axes([0.15,0.15,0.7,0.7])

df_oni = pd.DataFrame({'DATE': pd.date_range('1960-03', periods=682, freq='M'),
                       'ONI': (np.random.rand(682) - .5)*5})
df_oni['positive'] = df_oni.ONI>0

ax.bar(df_oni.DATE,df_oni.ONI, width=20, alpha=0.5, color=df_oni.positive.map({True: 'r', False: 'b'}))

ax.xaxis.set_major_locator(mdates.YearLocator(base=5))
ax.xaxis.set_major_formatter(mdates.DateFormatter("%Y"))
ax.xaxis.set_tick_params(rotation=0)

ax.yaxis.set_major_locator(mticker.MaxNLocator(integer=True, min_n_ticks=1))

ax.set_title("Indice ONI",fontsize= 14,fontweight="bold")
ax.set_ylabel("Valor del Índice\n", fontsize = 10.0)
ax.set_xlabel("")

enter image description here

  • Related