I want to add a vertical line in sns.pointplot()
, which has datetime xticks, I used ax.axvline
, but the position of the line was wrong.
my dataframe like this:
city | year | PM |
---|---|---|
c1 | 2011 | 2 |
c1 | 2012 | 2 |
c1 | 2013 | 3 |
c2 | 2011 | 3 |
c2 | 2012 | 2 |
c2 | 2013 | 3 |
my code like this:
df['year']=pd.to_datetime(df['year'])
fig,ax=plt.subplots()
g=sns.pointplot(x='year',
y='PM',
data=df,
ax=ax,
color='black',
scale=0.5,
capsize=0.2,
errwidth=0.8
)
ax.axvline(x=pd.Timestamp('2012-09-01 00:00:00'),
ymin=0,ymax=1,
#c="red",
ls='--',
linewidth=0.8,zorder=0, clip_on=False)
seaborn.pointplot
is 0 indexed like a bar plot. The ticks are not a datetime range like a line plot.
g.get_xticklabels() → [Text(0, 0, '2011-01-01'), Text(1, 0, '2012-01-01'), Text(2, 0, '2013-01-01')]
g.get_xticks() → array([0, 1, 2])
2012
is at tick 1
, so x=1 + 244days/365days
or x=1.67
(datetime.date(2012, 9, 1) - datetime.date(2012, 1, 1)).days → 244
python 3.8.11
, pandas 1.3.3
, matplotlib 3.4.3
, seaborn 0.11.2
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
data = {'city': ['c1', 'c1', 'c1', 'c2', 'c2', 'c2'], 'year': [2011, 2012, 2013, 2011, 2012, 2013], 'PM': [2, 2, 3, 3, 2, 3]}
df = pd.DataFrame(data)
# convert to datetime if desired
df['year'] = pd.to_datetime(df['year'], format='%Y').dt.date
fig, ax = plt.subplots()
g = sns.pointplot(x='year', y='PM', data=df, color='black', scale=0.5, capsize=0.2, errwidth=0.8, ax=ax)
g.axvline(x=1 + 244/365,
ymin=0, ymax=1, c="red", ls='--', linewidth=0.8, zorder=0, clip_on=False)