#!/usr/bin/env python
# coding: utf-8
# # Calliope Urban Scale Example Model
# In[1]:
import calliope
# We increase logging verbosity
calliope.set_log_level('INFO')
# In[2]:
model = calliope.examples.urban_scale()
# In[3]:
# Model inputs can be viewed at `model.inputs`.
# Variables are indexed over any combination of `techs`, `locs`, `carriers`, `costs` and `timesteps`,
# although `techs`, `locs`, and `carriers` are often concatenated.
# e.g. `chp`, `X1`, `heat` -> `X1::chp::heat`
model.inputs
# In[4]:
# Individual data variables can be accessed easily, `to_pandas()` reformats the data to look nicer
model.inputs.resource.to_pandas()
# In[5]:
# To reformat the array, deconcatenating loc_techs / loc_tech_carriers, you can use model.get_formatted_array()
# You can then apply loc/tech/carrier only operations, like summing information over locations:
model.get_formatted_array('resource').sum('locs').to_pandas()
# In[6]:
# Solve the model. Results are loaded into `model.results`.
# By including logging (see package importing), we can see the timing of parts of the run, as well as the solver's log
model.run()
# In[7]:
# Model results are held in the same structure as model inputs.
# The results consist of the optimal values for all decision variables, including capacities and carrier flow
# There are also results, like system capacity factor and levelised costs, which are calculated in postprocessing
# before being added to the results Dataset
model.results
# In[8]:
# We can sum heat output over all locations and turn the result into a pandas DataFrame
df_heat = model.get_formatted_array('carrier_prod').loc[{'carriers':'heat'}].sum('locs').to_pandas().T
#The information about the dataframe tells us about the amount of data it holds in the index and in each column
df_heat.info()
# In[9]:
# Using .head() to see the first few rows of heat generation and demand
# Note: carrier production in heat_pipes:N1 is heat received by the heat network at any location connected to `N1`
df_heat.head()
# In[10]:
# We can plot this by using the timeseries plotting functionality.
# The top-left dropdown gives us the chance to scroll through other timeseries data too.
model.plot.timeseries()
# In[11]:
# plot.capacities gives a graphical view of the non-timeseries variables, both input and output
model.plot.capacity()
# In[12]:
# We can also examine total technology costs
# notice all the NaN values which appear when seperating loc::techs to locs and techs.
# Any NaN value means we never considered that combination of `loc` and `tech` for the variable
costs = model.get_formatted_array('cost').loc[{'costs': 'monetary'}].to_pandas()
costs
# In[13]:
# We can examine levelized costs for each location and technology
lcoes = model.results.systemwide_levelised_cost.loc[{'carriers': 'electricity', 'costs':'monetary'}].to_pandas()
lcoes
# In[14]:
# We can just plot this directly using calliope analysis functionality
model.plot.capacity(array='systemwide_levelised_cost')
# In[15]:
# Plotting a map of locations and transmission lines is easily possible
# In our example, the system is purely hypothetical and the resulting map
# gives us little useful information...
model.plot.transmission()
# In[16]:
# Transmission plots give us a static picture of installed capacity along links.
# If we want timeseries data on energy flows at locations and along links
# we can use energy flow plotting. We only show the first day here, to improve loading speed.
model.plot.flows(timestep_index_subset=[0, 24])
# In[17]:
# `cufflinks` allows for easy plotly plots to be
# produced from a pandas DataFrame
##
# ATTENTION: To run this final part of the tutorial,
# you need to run `pip install cufflinks`
##
import cufflinks
cufflinks.go_offline()
# In[18]:
# We might like to plot the costs table from further above,
# which is outside the scope of internal calliope analysis functions
# But by using cufflinks, we can plot directly from our pandas DataFrame
# Note that the colours are not correct for our technologies here,
# as they come from the default colour theme applied by cufflinks
costs.iplot(kind='bar')
# ---
# See the [Calliope documentation](https://calliope.readthedocs.io/) for more details on setting up and running a Calliope model.