1

I generated a boxplot using seaborn. On the x axis, I would like to have, both the number of days (20, 25, 32) and the actual dates they refer to (2022-05-08, 2022-05-13, 2022-05-20). I found a potential solution at the following link add custom tick with matplotlib. I'm trying to adapt it to my problem but I could only get the number of days or the dates, not both. I really would appreciate any help. Thank you in advance for your time. Please, find below my code and the desired output.

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

df = pd.DataFrame({'nb_days':[20,20,20,25,25,20,32,32,25,32,32],
             'Dates':['2022-05-08','2022-05-08','2022-05-08','2022-05-13','2022-05-13','2022-05-08','2022-05-20','2022-05-20','2022-05-13','2022-05-20','2022-05-20'],
             'score':[3,3.5,3.4,2,2.2,3,5,5.2,4,4.3,5]})

df['Dates'] = df['Dates'].apply(pd.to_datetime)
tick_label = dict(zip(df['nb_days'],df['Dates'].apply(lambda x: x.strftime('%Y-%m-%d')))) #My custom xtick label

#Plot
fig,ax = plt.subplots(figsize=(6,6))
ax = sns.boxplot(x='nb_days',y='score',data=df,color=None)
# iterate over boxes to change color
for i,box in enumerate(ax.artists):
    box.set_edgecolor('red')
    box.set_facecolor('white')

sns.stripplot(x='nb_days',y='score',data=df,color='black')
ticks = sorted(df['nb_days'].unique())
labels = [tick_label.get(t, ticks[i]) for i,t in enumerate(ticks)]
ax.set_xticklabels(labels)

plt.tight_layout()
plt.show()
plt.close()


Here is the desired output.

output

petezurich
  • 9,280
  • 9
  • 43
  • 57
Amilovsky
  • 397
  • 6
  • 15

2 Answers2

2

You can do that by adding these lines in place of ax.set_xticklabels(labels)

new_labels=["{}\n{}".format(a_, b_) for a_, b_ in zip(ticks, labels)]
ax.set_xticklabels(new_labels)

Output

enter image description here

Redox
  • 9,321
  • 5
  • 9
  • 26
1

Try this:

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

    df = pd.DataFrame({'nb_days':[20,20,20,25,25,20,32,32,25,32,32],
                'Dates':['2022-05-08','2022-05-08','2022-05-08','2022-05-13','2022-05-13','2022-05-08','2022-05-20','2022-05-20','2022-05-13','2022-05-20','2022-05-20'],
                'score':[3,3.5,3.4,2,2.2,3,5,5.2,4,4.3,5]})

    df['Dates'] = df['Dates'].apply(pd.to_datetime)
    tick_label = dict(zip(df['nb_days'],df['Dates'].apply(lambda x: x.strftime('%Y-%m-%d')))) #My custom xtick label

    #Plot
    fig,ax = plt.subplots(figsize=(6,6))
    ax = sns.boxplot(x='nb_days',y='score',data=df,color=None)
    # iterate over boxes to change color
    for i,box in enumerate(ax.artists):
        box.set_edgecolor('red')
        box.set_facecolor('white')

    sns.stripplot(x='nb_days',y='score',data=df,color='black')
    ticks = sorted(df['nb_days'].unique())
    labels = ["{}\n".format(t)+tick_label.get(t, ticks[i]) for i, t in enumerate(ticks)]
    ax.set_xticklabels(labels)

    plt.tight_layout()
    plt.show()
    plt.close()

enter image description here

Iran Ribeiro
  • 101
  • 6