Reputation: 231
I am currently working on visualizing datasets with Seaborn and Pandas. I have some time-dependent data that I would like to graph in bar charts.
However, I am battling with two issues in Seaborn:
I have found a solution for my issues in normal Matplotlib, which is:
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import numpy as np
N = 20
np.random.seed(2022)
dates = pd.date_range('1/1/2014', periods=N, freq='m')
df = pd.DataFrame(
data={'dt':dates, 'val': np.random.randn(N)}
)
fig, ax = plt.subplots(figsize=(10, 6))
ax.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m'))
ax.bar(df['dt'], df['val'], width=25, align='center')
However, I already have most of my graphs done in Seaborn, and I would like to stay consistent. Once I convert the previous code into Seaborn, I lose the ability to format the dates:
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import numpy as np
N = 20
np.random.seed(2022)
dates = pd.date_range('1/1/2014', periods=N, freq='m')
df = pd.DataFrame(
data={'dt':dates, 'val': np.random.randn(N)}
)
fig, ax = plt.subplots(1,1)
ax.xaxis.set_major_formatter(mdates.DateFormatter('%y-%m'))
sns.barplot(x='dt', y='val', data=df)
fig.autofmt_xdate()
When I run the code, the date format remains unchanged and I can't locate any dates with DateLocator.
Is there any way for me to format my X-Axis for dates in Seaborn in a way similar to Matplotlib with DateLocator and DateFormatter?
Upvotes: 1
Views: 5536
Reputation: 339775
No, you cannot use seaborn.barplot
in conjunction with matplotlib.dates
ticking. The reason is that the ticks for seaborn barplots are at integer positions (0,1,..., N-1). So they cannot be interpreted as dates.
You have three options:
matplotlib.dates
tickers available.python 3.10
, pandas 1.5.0
, matplotlib 3.5.2
, seaborn 0.12.0
N = 20
np.random.seed(2022)
dates = pd.date_range('1/1/2014', periods=N, freq='m')
df = pd.DataFrame(data={'dates': dates, 'val': np.random.randn(N)})
# change the datetime format in the dataframe prior to plotting
df.dates = df.dates.dt.strftime('%Y-%m')
fig, ax = plt.subplots(1,1)
sns.barplot(x='dates', y='val', data=df)
xticks = ax.get_xticks()
xticklabels = [x.get_text() for x in ax.get_xticklabels()]
_ = ax.set_xticks(xticks, xticklabels, rotation=90)
N = 20
np.random.seed(2022)
dates = pd.date_range('1/1/2014', periods=N, freq='m')
df = pd.DataFrame(data={'dates': dates, 'val': np.random.randn(N)})
df.dates = df.dates.dt.strftime('%Y-%m')
fig, ax = plt.subplots(figsize=(10, 6))
sns.barplot(x='dates', y='val', data=df)
xticks = ax.get_xticks()
xticklabels = [x.get_text() if not i%2 == 0 else '' for i, x in enumerate(ax.get_xticklabels())]
_ = ax.set_xticks(xticks, xticklabels)
Upvotes: 5