Julio Ludovic Ramihone
Julio Ludovic Ramihone

Reputation: 339

Plotting a vertical line for df.plot.bar works, but it doesn't for a lineplot

I followed all step following my question here : Pandas Dataframe : How to add a vertical line with label to a bar plot when your data is time-series?

it was supposed to solve my problem but when I change the The kind of plot to line , the vertical line did not appear . I copy the same code and change plot type to line instead of bar :

as you can see with bar , the vertical line (in red ) appears .

# function to plot a bar 
def dessine_line3(madataframe,debut_date , mes_colonnes):

madataframe.index = pd.to_datetime(madataframe.index,format='%m/%d/%y')
df = madataframe.loc[debut_date:,mes_colonnes].copy()
filt = (df[df.index == '4/20/20']).index
df.index.searchsorted(value=filt)
fig,ax = plt.subplots()
df.plot.bar(figsize=(17,8),grid=True,ax=ax)
ax.axvline(df.index.searchsorted(filt), color="red", linestyle="--", lw=2, label="lancement")
plt.tight_layout()

out : enter image description here

but whan I just change code by changing the type of plot to line : there is no vertical line and also the x axis (date ) changed . enter image description here

so I wrote another code juste to draw line with vertical line

ax = madagascar_maurice_case_df[["Madagascar Covid-19 Ratio","Maurice Covid-19 Ratio"]].loc['3/17/20':].plot.line(figsize=(17,7),grid=True)

filt = (df[df.index=='4/20/20']).index ax.axvline(df.index.searchsorted(filt),color="red",linestyle="--",lw=2 ,label="lancement") plt.show()

but the result is the same

following the comment below , here is my final code :

def dessine_line5(madataframe,debut_date , mes_colonnes):
    plt.figure(figsize=(17,8))
    plt.grid(b=True,which='major',axis='y')
    df = madataframe.loc[debut_date:,mes_colonnes]
    sns.lineplot(data=df)
    lt = datetime.toordinal(pd.to_datetime('4/20/20'))
    plt.axvline(lt,color="red",linestyle="--",lw=2,label="lancement")
    plt.show()

and the result is : enter image description here

Upvotes: 1

Views: 1036

Answers (1)

Trenton McKinney
Trenton McKinney

Reputation: 62583

Plot tick locs

  • The issue is the plot tick locations are a different style depending on plot kind and api
    • df.plot vs. plt.plot vs. sns.lineplot
  • Place ticks, labels = plt.xticks() after df.plot.bar(figsize=(17,8),grid=True,ax=ax) and printing ticks will give array([0, 1, 2,..., len(df.index)]), which is why df.index.searchsorted(filt) works, it produces an integer location.
  • df.plot() has tick locs like array([13136, 13152, 13174, 13175], dtype=int64), for my sample date range. I don't actually know how those numbers are derived, so I don't know how to convert the date to that format.
  • sns.lineplot and plt.plot have tick locs that are the ordinal representation of the datetime, array([737553., 737560., 737567., 737577., 737584., 737591., 737598., 737607.]

For a lineplot with your example:

import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
from datetime import datetime

sns.lineplot(data=df)
lt = datetime.toordinal(pd.to_datetime('2020/04/20'))
plt.axvline(lt, color="red", linestyle="--", lw=2, label="lancement")
plt.show()

For my example data:

import numpy as np

data = {'a': [np.random.randint(10) for _ in range(40)],
        'b': [np.random.randint(10) for _ in range(40)],
        'date': pd.bdate_range(datetime.today(), periods=40).tolist()}

df = pd.DataFrame(data)
df.set_index('date', inplace=True)

sns.lineplot(data=df)
ticks, labels = plt.xticks()
lt = datetime.toordinal(pd.to_datetime('2020-05-19'))
plt.axvline(lt, color="red", linestyle="--", lw=2, label="lancement")
plt.show()

enter image description here

Upvotes: 1

Related Questions