【问题标题】:Plot seperate seasonal plots with datetime dataframe使用日期时间数据框绘制单独的季节性图
【发布时间】:2022-06-18 03:26:11
【问题描述】:

我有一个数据框df

    Date    station_name    BD_val      TEMIS_val   ratio       longitude   latitude
0   2003-01 29              295.448387  291.225806  -1.429211   158.950 -   54.500
1   2003-01 57              282.258065  279.290323  -1.051429   -26.130     -75.360
2   2003-01 57              282.258065  279.290323  -1.051429   -26.600     -75.583
3   2003-01 101             310.516129  304.677419  -1.880324   39.580      -69.010
4   2003-01 111             268.071429  274.000000  2.211564    -24.800     -89.983
... ... ... ... ... ... ... ...
153 2003-12 400             294.733333  300.000000  1.786926    11.450      -70.450
154 2003-12 454             298.176667  294.000000  -1.400736   -67.106     -68.130
155 2003-12 473             308.433333  316.000000  2.453258    -70.850     -53.140
156 2003-12 478             309.306667  304.000000  -1.715665   76.380      -69.370

Date 是日期时间格式。

我想创建 4 个图:从 1 月到 3 月开始,每个图持续三个月,其中latitude 在 x 轴上,ratio 在 y 轴上。我希望每个月都成为该特定子图中的一行。

我该怎么做呢?

到目前为止,我使用了以下方法:

for key, grp in comp_df_complete.groupby(['Date']):
    grp = grp.sort_values(by=['latitude'])
    plt.plot(grp.latitude, grp.ratio)

plt.legend()
plt.show()

结果如下图:

这很接近,问题是它很混乱,而且我希望在 4 个季节中的每个月也能在 4 个多面的情节中看到。此外,传说似乎不适用于这种方法,但这是另一个问题:

No artists with labels found to put in legend. Note that artists whose label start with an underscore are ignored when legend() is called with no argument.

我最终想要的是一个类似于这个的图:

但是,latitude 位于 x 轴,ratio 位于 y 轴,每个图在特定季节的每个月中显示三行。

【问题讨论】:

  • 我将用我尝试过的内容来编辑文本。
  • 我已经添加了一个部分,其中包含我目前所拥有的内容!
  • 列日期可能不是日期时间,但它是什么?一个字符串、一个句点、一个时间戳,还是别的什么? df.dtypes 说什么? pandas/matplotlib 的反应因类型而异。
  • 您可以创建 4 个子图并在每个子图中调整您的代码,例如:for key, grp in df.groupby(['Date']): grp = grp.sort_values(by=['latitude'] ) ; crit = grp['Date'].isin(['2003-01', '2003-02', '2003-03']) ; plt.plot(grp[crit].latitude,grp[crit].ratio)
  • 什么代码生成这种格式的日期时间对象?无论如何,我认为这是创建一个月和 quarter 列进行子图绘制的简单方法。 seaborn 可能会让您的生活更轻松。

标签: python pandas matplotlib time-series


【解决方案1】:

假设 Date 中的值是字符串,想法是添加一个列给出“季节”,并为每个列按 Date 分组以获取给定季节每个月的行:

df['season'] = df['Date'].apply(lambda x: (int(x[-2:])-1)//3+1)
fig = plt.figure(figsize=(16, 12))

for i in range(4):  
    ax = fig.add_subplot(2, 2, i+1)
    for key, grp in df[df['season']==i+1].groupby(['Date']):
        grp = grp.sort_values(by=['latitude'])
        ax.plot(grp.latitude, grp.ratio)
plt.show()

编辑:如果 'Date' 是日期时间 -> df['season'] = df['Date'].dt.quarter

【讨论】:

  • 日期列中的值为日期时间格式
  • 日期时间对象的等价物是df["season"] = df['Date'].dt.month.apply(lambda x: (x-1)//3+1)
  • 谢谢,这是一个很好的开始。
【解决方案2】:

这应该对你有帮助。

import requests
import pandas as pd
from pandas import DataFrame
import matplotlib.pyplot as plt
import seaborn as sns

# Intitialise data of lists
data = [{'Month': '2020-01-01', 'Expense':1000, 'ID':'123'}, 
       {'Month': '2020-02-01', 'Expense':3000, 'ID':'123'},
       {'Month': '2020-03-01', 'Expense':7000, 'ID':'123'}, 
       {'Month': '2020-01-01', 'Expense':3000, 'ID':'456'},
       {'Month': '2020-02-01', 'Expense':5000, 'ID':'456'}, 
       {'Month': '2020-03-01', 'Expense':5000, 'ID':'456'},
       {'Month': '2020-03-01', 'Expense':5000, 'ID':'789'},
       {'Month': '2020-04-01', 'Expense':6000, 'ID':'789'}]
df = pd.DataFrame(data)
df

uniques = df['ID'].unique()

for i in uniques:
    df_single = df[df['ID']==i]
    sns.lineplot(data=df_single, x='Month', y='Expense')
    plt.show()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-10-04
    • 2016-11-11
    • 2021-03-20
    • 2021-07-25
    • 2012-02-06
    • 1970-01-01
    • 2017-10-22
    • 1970-01-01
    相关资源
    最近更新 更多