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
Out[3]:
In [4]:
# Individual data variables can be accessed easily, `to_pandas()` reformats the data to look nicer
model.inputs.resource.to_pandas()
Out[4]:
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()
Out[5]:
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
Out[7]:
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()
Out[9]:
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
Out[12]:
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
Out[13]:
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 for more details on setting up and running a Calliope model.