#!/usr/bin/env python # coding: utf-8 # # Calliope Urban Scale Example Model # In[1]: import calliope # We increase logging verbosity calliope.set_log_verbosity('INFO', include_solver_output=False) # 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]) # --- # See the [Calliope documentation](https://calliope.readthedocs.io/) for more details on setting up and running a Calliope model.