【问题标题】:format x-axis (dates) in sns.lmplot()在 sns.lmplot() 中格式化 x 轴(日期)
【发布时间】:2021-12-09 17:53:53
【问题描述】:

我有需要用sns.lmplot() 绘制的每日数据。

数据结构如下:

df = pd.DataFrame(columns=['date', 'origin', 'group', 'value'],
                  data = [['2001-01-01', "Peter", "A", 1.0],
                          ['2011-01-01', "Peter", "A", 1.1],
                          ['2011-01-02', "Peter", "B", 1.2],
                          ['2012-01-03', "Peter", "A", 1.3],
                          ['2012-01-01', "Peter", "B", 1.4],
                          ['2013-01-02', "Peter", "A", 1.5],
                          ['2013-01-03', "Peter", "B", 1.6],
                          ['2021-01-01', "Peter", "A", 1.7]])

我现在想用sns.lmplot() 绘制每月平均值的数据(我的原始数据比玩具数据更细粒度),并使用hue 绘制group 列。为此,我按月汇总:

df['date'] = pd.to_datetime(df['date']).dt.strftime('%Y%M').astype(int)
df = df.groupby(['date', 'origin', 'group']).agg(['mean'])
df.columns = ["_".join(pair) for pair in df.columns]  # reset col multi-index
df = df.reset_index()  # reset index

然后我绘制数据:

sns.lmplot(data=df, x="date", y="value", hue="group",
           ci=None, truncate=False, scatter_kws={"s": 1}, lowess=True, height=6, aspect=1.25)
plt.title(f"Title.")
plt.ylabel("Value")
plt.show()

这很好用,但日期很乱。我希望它们显示为日期而不是 ints。

我找到了this 的问题,但我想要分组图,所以我不能使用regplot,并且代码plt.xticks(fake_dates)(在this 答案之后)给出TypeError: object of type 'FuncFormatter' has no len()

有人知道如何解决这个问题吗?

【问题讨论】:

    标签: python datetime matplotlib plot seaborn


    【解决方案1】:
    • 为了将 x 轴上的值转换回日期,'date' 列中的值应转换为序数值。
    • 在遍历坐标区以配置xtick 格式时,可以使用.strftime 将标签配置为自定义字符串格式
      • new_labels = [date.fromordinal(int(label)).strftime("%b %Y") for label in labels]
    • python 3.8.12pandas 1.3.3matplotlib 3.4.3seaborn 0.11.2 中测试
    from datetime import date
    
    # convert the date column to ordinal or create a new column
    df['date'] = pd.to_datetime(df['date']).apply(lambda date: date.toordinal())
    
    df = df.groupby(['date', 'origin', 'group']).agg(['mean'])
    df.columns = ["_".join(pair) for pair in df.columns]  # reset col multi-index
    df = df.reset_index()  # reset index
    
    # plot
    g = sns.lmplot(data=df, x="date", y="value_mean", hue="group", ci=None, truncate=False, scatter_kws={"s": 1}, lowess=True, height=6, aspect=1.5)
    
    # iterate through the axes of the figure-level plot
    for ax in g.axes.flat:
        labels = ax.get_xticks() # get x labels
        new_labels = [date.fromordinal(int(label)) for label in labels] # convert ordinal back to datetime
        ax.set_xticks(labels)
        ax.set_xticklabels(new_labels, rotation=0) # set new labels
    
    plt.title("Title")
    plt.ylabel("Value")
    plt.show()
    

    【讨论】:

    • 谢谢你,这很好用! "
    • @Ivo 不客气。我很高兴这对你有用。
    • 为了后代,将行 new_labels = [date.fromordinal(int(label)) for label in labels] 更改为 new_labels = [date.fromordinal(int(label)).strftime("%b %Y") for label in labels] 允许根据 strftime 语法以所需的方式更改 xticks。 :)
    • 抱歉,这就是我的意思 - “允许更改所需的 xtickLABEL”。 (而且我没有具体询问,所以你不可能知道。感谢更新!
    • 很好的解决方案!我尝试了很多不同的方法,但这是唯一有效的方法。这也很简单。
    猜你喜欢
    • 2014-08-12
    • 2012-07-29
    • 1970-01-01
    • 2014-06-06
    • 2020-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多