import calliope
# cufflinks allows for easy plotly plots to be
# produced from a pandas DataFrame
import cufflinks
# We increase logging verbosity
calliope.set_log_level('INFO')
model = calliope.examples.urban_scale()
# 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
# Individual data variables can be accessed easily, `to_pandas()` reformats the data to look nicer
model.inputs.resource.to_pandas()
# 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()
# 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()
# 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
# 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()
# 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()
# 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()
# plot.capacities gives a graphical view of the non-timeseries variables, both input and output
model.plot.capacity()
# 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
# We might like to plot this, 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
costs.iplot(kind='bar')
# We can examine levelized costs for each location and technology
lcoes = model.results.systemwide_levelised_cost.loc[{'carriers': 'electricity', 'costs':'monetary'}].to_pandas()
lcoes
# We could plot this using lcoes.iplot(kind='bar', title='Systemwide levelised costs')
# Or we can just plot it directly using calliope analysis functionality
model.plot.capacity(array='systemwide_levelised_cost')
# 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()
See the Calliope documentation for more details on setting up and running a Calliope model.