如何将有间隙的数据绘制到子图中

2024-05-23 02:59:00 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个有间隙的数据框

                                    temperature 
    data                                                        
    2016-01-01 01:00:00              -8.2 
    2016-01-01 02:00:00              -8.3  
    2016-01-01 03:00:00              -9.1 
    2016-01-01 04:00:00              -9.1  
    2016-01-01 05:00:00              -9.6 
        ...                           ...     
    2020-02-29 20:00:00               5.9   
    2020-02-29 21:00:00               5.4   
    2020-02-29 22:00:00               4.7 
    2020-02-29 23:00:00               4.3 
    2020-03-01 00:00:00               4.3

以下是一些示例数据的代码,与我的不同,但概念相同:

def tworzeniedaty():
    import pandas as pd
    rng1 = list(pd.date_range(start='2016-01-01', end='2016-02-29', freq='D'))
    rng2 = list(pd.date_range(start='2016-12-15', end='2017-02-28', freq='D'))
    rng3 = list(pd.date_range(start='2017-12-15', end='2018-02-28', freq='D'))
    rng4 = list(pd.date_range(start='2018-12-15', end='2019-02-28', freq='D'))
    rng5 = list(pd.date_range(start='2019-12-15', end='2020-02-29', freq='D'))
    return rng1 + rng2 + rng3 + rng4 + rng5


import random
import pandas as pd

lista = [random.randrange(1, 10, 1) for i in range(len(tworzeniedaty()))]
df = pd.DataFrame({'Date': tworzeniedaty(), 'temperature': lista})
df['Date'] = pd.to_datetime(df['Date'], format="%Y/%m/%d")

当我绘制数据时,我得到了一个非常混乱的图。 enter image description here

相反,我想得到:

enter image description here

这与How to plot only specific months in a time series of several years?是同一个问题,但我想用python来做,并且不能破译R代码


Tags: 数据代码importpandasdfdaterangestart
2条回答

我们可以通过计算日期之间的差异并检查是否超过三个月这样的限制来对数据进行分组:

from matplotlib import pyplot as plt
import random
import pandas as pd

def tworzeniedaty():
    rng1 = list(pd.date_range(start='2016-01-01', end='2016-02-29', freq='D'))
    rng2 = list(pd.date_range(start='2016-12-15', end='2017-02-28', freq='D'))
    rng3 = list(pd.date_range(start='2017-12-15', end='2018-02-28', freq='D'))
    rng4 = list(pd.date_range(start='2018-12-15', end='2019-02-28', freq='D'))
    rng5 = list(pd.date_range(start='2019-12-15', end='2020-02-29', freq='D'))
    return rng1 + rng2 + rng3 + rng4 + rng5

lista = [random.randrange(1, 10, 1) for i in range(len(tworzeniedaty()))]
df = pd.DataFrame({'Date': tworzeniedaty(), 'temperature': lista})


#assuming that the df is sorted by date, we look for gaps of more than 3 months
#then we label the groups with consecutive numbers
df["groups"] = (df["Date"].dt.month.diff() > 3).cumsum()
n = 1 + df["groups"].max()

#creating the desired number of subplots
fig, axes = plt.subplots(1, n, figsize=(15, 5), sharey=True)

#plotting each group into a subplot
for (i, group_df), ax in zip(df.groupby("groups"), axes.flat):
    ax.plot(group_df["Date"], group_df["temperature"])
      
fig.autofmt_xdate(rotation=45)    
plt.tight_layout()
plt.show()

样本输出:

enter image description here

显然,如果存在更多的组,则需要进行一些微调。在这种情况下,网格将是合适的-可以create a subplot grid and remove unnecessary subplots like in this matplotlib example。x标签可能还需要使用a matplotlib Locator and Formatter进行一些调整,以获得更好的外观。其中一些可以使用带有^{} in seaborn的分组变量自动完成;然而,这可能会导致一系列不同的问题

我认为最好的方法是过滤掉Jun/Jul/Aug数据,就像R代码中所做的那样。这将有助于:

def tworzeniedaty():
    import pandas as pd
    rng1 = list(pd.date_range(start='2016-01-01', end='2016-02-29', freq='D'))
    rng2 = list(pd.date_range(start='2016-12-15', end='2017-02-28', freq='D'))
    rng3 = list(pd.date_range(start='2017-12-15', end='2018-02-28', freq='D'))
    rng4 = list(pd.date_range(start='2018-12-15', end='2019-02-28', freq='D'))
    rng5 = list(pd.date_range(start='2019-12-15', end='2020-02-29', freq='D'))
    return rng1 + rng2 + rng3 + rng4 + rng5


import random
import pandas as pd

import matplotlib.pyplot as plt

lista = [random.randrange(1, 10, 1) for i in range(len(tworzeniedaty()))]
df = pd.DataFrame({'Date': tworzeniedaty(), 'temperature': lista})
df['Date'] = pd.to_datetime(df['Date'], format="%Y/%m/%d")

years = list(set(df.Date.dt.year))


fig, ax = plt.subplots(1, len(years))
for i in years:
        df_set =  df[df.Date.dt.year == i]
        df_set.set_index("Date", inplace = True)
        df_set.index = df_set.index.map(str)
        ax[years.index(i)].plot(df_set)
        ax[years.index(i)].title.set_text(i)

plt.show()

相关问题 更多 >

    热门问题