#!/usr/bin/env python # coding: utf-8 # # EnergyPlus Output Data Analysis Example # # Created by Clayton Miller (miller.clayton@arch.ethz.ch) # # The goal of this notebook is to give a user a glimpse at the loading and manipulation of a .csv output of EnergyPlus # # Execute the cells in this notebook one at a time and try to understand what each code snippet is doing. There will be text notation before many of the cells attempting to explain what is going on. # First we load some libraries that we will use. # In[ ]: import pandas as pd import datetime from datetime import timedelta import time # In[ ]: get_ipython().run_line_magic('matplotlib', 'inline') # The following is a Python `fucntion` that I created ot read a .csv file, do a conversion and change the timestamp # In[ ]: def loadsimdata(file,pointname,ConvFactor): df = pd.read_csv(file) df['desiredpoint'] = df[pointname]*ConvFactor df.index = eplustimestamp(df) pointdf = df['desiredpoint'] return pointdf # ## Open an EnergyPlus Output CSV file # # First let's open the .csv output file from an EnergyPlus run and visualize it. # In[ ]: SimulationData = pd.read_csv('EnergyplusSimulationData.csv') # In[ ]: SimulationData # We can select a certain column and see what's inside -- there is quite a few columns in this output file. We can see using the `.info` function from pandas that there are 256 columns # In[ ]: SimulationData.info() # In[ ]: SimulationData['AIRNODE_ZONENODE_U1_S:System Node Setpoint Temp[C](Hourly) ']#.plot() # In[ ]: SimulationData['Date/Time'].tail() # ### We need to convert 24:00:00 to 00:00:00 for it to play nice with Pandas # In[ ]: #Function to convert timestamps def eplustimestamp(simdata): timestampdict={} for i,row in simdata.T.iteritems(): timestamp = str(2013) + row['Date/Time'] try: timestampdict[i] = datetime.datetime.strptime(timestamp,'%Y %m/%d %H:%M:%S') except ValueError: tempts = timestamp.replace(' 24', ' 23') timestampdict[i] = datetime.datetime.strptime(tempts,'%Y %m/%d %H:%M:%S') timestampdict[i] += timedelta(hours=1) timestampseries = pd.Series(timestampdict) return timestampseries # In[ ]: SimulationData.index = eplustimestamp(SimulationData) # In[ ]: SimulationData.info() # In[ ]: SimulationData['AIRNODE_ZONENODE_U1_S:System Node Setpoint Temp[C](Hourly) '] # In[ ]: ColumnsList = pd.Series(SimulationData.columns) ColumnsList.head(100) # ## Built-in String Query functions to find desired columns # # We can use the string query functions in Pandas to find columns to select for visualization, etc without manually inputting them. # # In[ ]: ColumnsList.str.endswith("Zone Mean Air Temperature [C](Hourly)") # In[ ]: ColumnsList[(ColumnsList.str.endswith("Zone Mean Air Temperature [C](Hourly)"))] # In[ ]: ZoneTempPointList = list(ColumnsList[(ColumnsList.str.endswith("Zone Mean Air Temperature [C](Hourly)"))]) ZoneTempPointList # In[ ]: BasementZoneTemp = list(ColumnsList[(ColumnsList.str.endswith("Zone Mean Air Temperature [C](Hourly)"))&(ColumnsList.str.contains("U1"))]) GroundFloorZoneTemp = list(ColumnsList[(ColumnsList.str.endswith("Zone Mean Air Temperature [C](Hourly)"))&(ColumnsList.str.contains("00"))]) Floor1ZoneTemp = list(ColumnsList[(ColumnsList.str.endswith("Zone Mean Air Temperature [C](Hourly)"))&(ColumnsList.str.contains("01"))]) Floor2ZoneTemp = list(ColumnsList[(ColumnsList.str.endswith("Zone Mean Air Temperature [C](Hourly)"))&(ColumnsList.str.contains("02"))]) Floor3ZoneTemp = list(ColumnsList[(ColumnsList.str.endswith("Zone Mean Air Temperature [C](Hourly)"))&(ColumnsList.str.contains("03"))]) Floor4ZoneTemp = list(ColumnsList[(ColumnsList.str.endswith("Zone Mean Air Temperature [C](Hourly)"))&(ColumnsList.str.contains("04"))]) # In[ ]: ZoneTemp = SimulationData[ZoneTempPointList]#.drop(['EMS:All Zones Total Heating Energy {J}(Hourly)'],axis=1) # In[ ]: ZoneTemp.info() # ## Visualization # # Now that we have the data in a Pandas Dataframe, let's do some analysis -- visualization, statistics, etc # In[ ]: ZoneTemp.plot(figsize=(25,15)) # In[ ]: ZoneTemp[BasementZoneTemp].plot(figsize=(25,10)) # In[ ]: ZoneTemp[GroundFloorZoneTemp].truncate(before='2013-03-10',after='2013-03-14').plot(figsize=(25,10)) # In[ ]: ZoneTemp[Floor1ZoneTemp].plot(figsize=(25,10)) # In[ ]: ZoneTemp[Floor2ZoneTemp].plot(figsize=(25,10)) # ## Zooming in using the `.truncate()` pandas method # In[ ]: SimulationData['Environment:Outdoor Dry Bulb [C](Hourly)'].truncate(before='2013-03-10',after='2013-03-14').plot(figsize=(25,10)) # ## Let's take a deeper look at the Floor 2 Zone Temperations # In[ ]: Floor2Temps = ZoneTemp[Floor2ZoneTemp] # In[ ]: Floor2Temps.info() # In[ ]: Floor2Temps.describe() # ## Heatmaps # # Heatmaps are a great way to visualize performance data # In[ ]: import pandas as pd import matplotlib.pyplot as plt import numpy as np from matplotlib.backends.backend_pdf import PdfPages import os import matplotlib.dates as mdates import datetime as dt # In[ ]: Floor1Energy = list(ColumnsList[(ColumnsList.str.endswith("Total Heating Energy {J}(Hourly)"))&(ColumnsList.str.contains("01"))]) # In[ ]: Floor1Energy # In[ ]: df_hourly = SimulationData.resample('H').mean() #Add the Date and time for pivoting df_hourly['Date'] = df_hourly.index.map(lambda t: t.date()) df_hourly['Time'] = df_hourly.index.map(lambda t: t.time()) # In[ ]: numberofplots = len(Floor1Energy) # In[ ]: pointcounter = 1 fig = plt.figure(figsize=(40, 4 * numberofplots)) for energypoint in Floor1Energy: print "Loading data from "+energypoint #Pivot df_pivot = pd.pivot_table(df_hourly, values=energypoint, index='Time', columns='Date') # Get the data x = mdates.drange(df_pivot.columns[0], df_pivot.columns[-1] + datetime.timedelta(days=1), dt.timedelta(days=1)) y = np.linspace(1, 24, 24) # Plot ax = fig.add_subplot(numberofplots, 1, pointcounter) data = np.ma.masked_invalid(np.array(df_pivot)) qmesh = ax.pcolormesh(x, y, data) cbar = fig.colorbar(qmesh, ax=ax) cbar.ax.tick_params(labelsize= 24) ax.axis('tight') try: plt.title(energypoint, fontsize=26) except IndexError: continue # Set up as dates ax.xaxis_date() fig.autofmt_xdate() fig.subplots_adjust(hspace=.5) pointcounter += 1 # In[ ]: # In[ ]: