Search code examples
pythonpython-3.xmatplotlibdatetimeaxvline

Using axvline with datetimeindex


I am trying to plot a vertical line using axvline, but I keep getting errors even though I saw here that it's possible to just feed in the date into axvline: Python/Matplotlib plot vertical line for specific dates in line chart

Could anyone point out what am I doing wrong (I am also a beginner). Ideally, I am looking for a way to just be able to feed in the date into axvline without adding extra pieces of code.

Here is my df:

    CPISXS  CPIX    WTI UMCSI
Dates               
2022-08-31  387.748 263.732 93.67   44.0
2022-09-30  390.555 264.370 84.26   42.0
2022-10-31  390.582 264.442 87.55   42.0
2022-11-30  390.523 263.771 84.37   46.0
2022-12-31  NaN NaN NaN NaN

<class 'pandas.core.frame.DataFrame'>
DatetimeIndex: 756 entries, 1960-01-31 to 2022-12-31
Freq: M
Data columns (total 4 columns):
     #   Column  Non-Null Count  Dtype  
    ---  ------  --------------  -----  
     0   CPISXS  480 non-null    float64
     1   CPIX    671 non-null    float64
     2   WTI     755 non-null    float64
     3   UMCSI   670 non-null    float64
    dtypes: float64(4)
    memory usage: 45.7 KB`

And here is the code:

fig2, m1 = plt.subplots(figsize=(12,6))
m2=m1.twinx()
m1.axvline(x='1990-01-30')
m1.plot(df0['UMCSI'],'r--',linewidth=1)
m2.plot(df0['WTI'],'b')

When I run it I always get the vertical line on 1970-01-01


Solution

  • Move axvline after the plot commands.

    Why the order matters:

    • If you use axvline first, the line gets added to a blank plot without a datetime x-axis. Since there is no datetime x-axis, axvline doesn't know what to do with a date string input.
    • Conversely if you plot the time series first, the datetime x-axis gets established, at which point axvline will understand the date input.
    fig2, m1 = plt.subplots(figsize=(12, 6))
    m2 = m1.twinx()
    
    # plot the time series first to establish the datetime x-axis
    m1.plot(df0['UMCSI'], 'r--', linewidth=1)
    m2.plot(df0['WTI'], 'b')
    
    # now axvline will understand the date input
    m1.axvline(x='1990-01-30')