Home > front end >  Python: Plotting average Weekdays in succession for different Seasons
Python: Plotting average Weekdays in succession for different Seasons

Time:07-16

I have a DateTimeSeries Dataframe with 15 Minutes values. Index is a DatetimeIndex. First Column holds the Values, 2nd the Day of the Week, 3rd the season. (I have custom defined seasons)

I would like to plot all the Season with their average hourly value per weekday in succession, Monday to Sunday. Something like this:

Plot Goal

I have managed to create 4 subplots, where each subplot represents one season, and all days of the week are depicted as an individual line. However, I can’t figure out how to plot one day after the other.

Here is what I got: My Plot

This is my code, but I created some random numbers, so the plot results don't make much sense. But I don’t want to bother anyone with my csv files:

import pandas as pd
import datetime as dt
import matplotlib.pyplot as plt
import matplotlib as mpl
import numpy as np

#Create DataFrame
df = pd.DataFrame()

df["date"] = pd.date_range(start='2018', end='2019', freq = "15Min")
df=df.set_index(["date"])

df['Day'] = df.index.weekday

dw_mapping={0: 'Mon', 1: 'Tue', 2: 'Wed', 3: 'Thu', 4: 'Fri', 5: 'Sat', 6: 'Sun'} 
df['Day']=df.index.weekday.map(dw_mapping)

df['season'] = df.index.month
season_mapping={1: 'Winter',     #Winter
            2: 'Winter',         #Winter
            3: 'eS/lF',    #EarlySpring / LateFall
            4: 'eS/lF',    #EarlySpring / LateFall
            5: 'lS/eF',       #LateSpring / EarlyFall
            6: 'Summer',  #Summer
            7: 'Summer',  #Summer
            8: 'Summer',  #Summer
            9: 'lS/eF',       #LateSpring / EarlyFall 
            10:'eS/lF', 
            11:'eS/lF',     #EarlySpring / LateFall
            12:'Winter'}          #Winter
df['season']=df.index.month.map(season_mapping)

df["B1W"] = 1
df['B1W'] = np.where(df['season'] == 'Winter', df['B1W'] * np.random.randint(30, 60, df.shape[0]), df["B1W"])
df['B1W'] = np.where(df['season'] == 'eS/lF', df['B1W'] *  np.random.randint(20, 50, df.shape[0]), df["B1W"])
df['B1W'] = np.where(df['season'] == 'lS/eF', df['B1W'] *  np.random.randint(10, 30, df.shape[0]), df["B1W"])
df['B1W'] = np.where(df['season'] == 'Summer', df['B1W'] * np.random.randint(0, 10, df.shape[0]), df["B1W"])

#### Create Plot #### 
mpl.rcParams['figure.dpi'] = 100
plt.style.use('ggplot')

ymin, ymax = 0, 50

fig, axes = plt.subplots(2, 2)
plt.subplots_adjust(wspace=0.2, hspace=0.3)
fig.suptitle("Building 1", fontsize=16)

fig.set_figheight(10)
fig.set_figwidth(15)

season = "Summer"
df.loc[df["season"]==season].groupby([df.loc[df["season"]==season].index.hour, 'Day'])["B1W"].mean().unstack().plot(
        ax=axes[0,0], ylim=(ymin,ymax), title = season, legend=False)

season = "eS/lF" #early Spring / late Fall
df.loc[df["season"]==season].groupby([df.loc[df["season"]==season].index.hour, 'Day'])["B1W"].mean().unstack().plot(
        ax=axes[0,1], ylim=(ymin,ymax), title = season, legend=False)

season = "lS/eF" #late Spring / early Fall
df.loc[df["season"]==season].groupby([df.loc[df["season"]==season].index.hour, 'Day'])["B1W"].mean().unstack().plot(
        ax=axes[1,0], ylim=(ymin,ymax), title = season, legend=False)

season = "Winter"
df.loc[df["season"]==season].groupby([df.loc[df["season"]==season].index.hour, 'Day'])["B1W"].mean().unstack().plot(
        ax=axes[1,1], ylim=(ymin,ymax), title = season, legend=False)

for ax in axes.flat:
    ax.set(xlabel='Time', ylabel='Power in MW')
    
for n in range(0,2):
    axes[n, 0].set_xticks([0,4,8,12,16,20])
    axes[n, 1].set_xticks([0,4,8,12,16,20])
    
# LEGEND
handles, labels = plt.gca().get_legend_handles_labels() # reorder Legend Labels
order = [1,5,6,4,0,2,3]      # specify order in Legend
axes[1,1].legend([handles[i] for i in order], [labels[i] for i in order], loc=1, ncol=7, 
                 bbox_to_anchor=(0.638,-0.2), frameon=True) # print and order LEGEND

CodePudding user response:

If I am understanding you correctly, you are attempting to produce a chart similar to the following.

Weekly Seasonal Chart

If so, following is a snippet of code with a simplified data set with one week of temperatures for each season.

import matplotlib.pyplot as plt

day     = ['Mon', 'Tues', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
winter  = [32, 41, 22, 15, 28, 36, 37]
earlyspring  = [46, 48, 40, 50, 52, 39, 55]
summer  = [68, 77, 66, 72, 80, 75, 88]
earlyfall    = [70, 55, 66, 69, 71, 58, 54]

plt.plot(day, winter,  label = "Winter")
plt.plot(day, earlyspring,  label = "Early Spring - Late Autumn")
plt.plot(day, summer,   label = "Summer")
plt.plot(day, earlyfall, label = "Early Autumn - Late Spring")
plt.legend()

plt.show()

Perhaps you could build upon that as a simple start. Each seasonal list would be filled with the data from your "CSV" file.

Hope that helps.

Regards.

CodePudding user response:

Switch to groupby([df.loc[df["season"]==season].index.day_name(), df.loc[df["season"]==season].index.hour]), the day of week day_name() should on the top level.

#### Create Plot ####
mpl.rcParams['figure.dpi'] = 100
plt.style.use('ggplot')

ymin, ymax = 0, 50

fig, axes = plt.subplots(2, 2)
plt.subplots_adjust(wspace=0.2, hspace=0.3)
fig.suptitle("Building 1", fontsize=16)

fig.set_figheight(10)
fig.set_figwidth(15)

season = "Summer"
df.loc[df["season"]==season].groupby([df.loc[df["season"]==season].index.day_name(), df.loc[df["season"]==season].index.hour])["B1W"].mean().unstack().plot(
    ax=axes[0,0], ylim=(ymin,ymax), title = season, legend=False)

season = "eS/lF" #early Spring / late Fall
df.loc[df["season"]==season].groupby([df.loc[df["season"]==season].index.day_name(), df.loc[df["season"]==season].index.hour])["B1W"].mean().unstack().plot(
    ax=axes[0,1], ylim=(ymin,ymax), title = season, legend=False)

season = "lS/eF" #late Spring / early Fall
df.loc[df["season"]==season].groupby([df.loc[df["season"]==season].index.day_name(), df.loc[df["season"]==season].index.hour])["B1W"].mean().unstack().plot(
    ax=axes[1,0], ylim=(ymin,ymax), title = season, legend=False)

season = "Winter"
df.loc[df["season"]==season].groupby([df.loc[df["season"]==season].index.day_name(), df.loc[df["season"]==season].index.hour])["B1W"].mean().unstack().plot(
    ax=axes[1,1], ylim=(ymin,ymax), title = season, legend=False)


enter image description here

  • Related