如何为seaborn箱线图添加同时显示天数与日期的自定义X轴刻度
问题描述
使用seaborn生成箱线图时,需要在X轴同时展示天数值(20、25、32)以及其对应的实际日期(2022-05-08、2022-05-13、2022-05-20)。自定义刻度时仅能单独显示天数或者单独显示日期,无法同时展示两类信息。
原始实现代码如下:
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()
预期输出效果:
实现方案
- 核心逻辑是构造双行刻度标签,利用matplotlib支持标签内换行的特性,将天数值和对应日期用换行符
\n拼接,不需要修改原有刻度位置,直接替换X轴标签即可实现两类信息同时展示。 - 仅需修改标签生成部分的代码,其余绘图、样式调整逻辑完全保留。
修正后完整代码
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')))) # 天数与日期映射关系 # 绘图 fig,ax = plt.subplots(figsize=(6,6)) ax = sns.boxplot(x='nb_days',y='score',data=df,color=None) # 调整箱线样式 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 = [f"{t}\n{tick_label[t]}" for t in ticks] ax.set_xticklabels(labels) plt.tight_layout() plt.show() plt.close()
运行代码后即可得到和预期一致的双行X轴刻度效果。
内容的提问来源于stack exchange,提问作者Amilovsky
相关产品推荐
相关产品推荐

