{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import warnings\n",
    "warnings.filterwarnings('ignore') # For better visibility, warnings are turned off in this notebook"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# FINE Webinar Part I: 2-nodal Electricity Supply System"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In this application of the FINE framework, an energy supply system, consisting of two-regions, is modeled and optimized.\n",
    "\n",
    "The workflow is structures as follows:\n",
    "-  Required packages are imported\n",
    "-  An energy system model instance is created\n",
    "-  Commodity sources are added to the energy supply system model\n",
    "-  Commodity conversion components are added to the energy supply system model\n",
    "-  Commodity storages are added to the energy supply system model\n",
    "-  Commodity transmission components are added to the energy supply system model\n",
    "-  Commodity sinks are added to the energy supply system model\n",
    "-  The energy supply system model is optimized\n",
    "-  Selected optimization results are presented"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Import required packages\n",
    "\n",
    "The FINE framework is imported which provides the required classes and functions for modeling the energy system."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "import FINE as fn         # Provides objects and functions to model an energy system \n",
    "import pandas as pd       # Used to manage data in tables\n",
    "import geopandas as gpd   # Used to display geo-referenced plots\n",
    "import shapely as shp     # Used to generate geometric objects\n",
    "import numpy as np        # Used to generate random input data\n",
    "np.random.seed(42)        # Sets a \"seed\" to produce the same random input data in each model run"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Model an energy system"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Create an energy system model instance \n",
    "\n",
    "The structure of the energy supply system model is given by the considered locations, commodities, the number of time steps as well as the hours per time step.\n",
    "\n",
    "The commodities are specified by a unit (i.e. 'GW_electric', 'GW_naturalGas_lowerHeatingValue', 'Mio. t CO2/h') which can be given as an energy or mass unit per hour. Furthermore, the cost unit and length unit are specified."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "code_folding": []
   },
   "outputs": [],
   "source": [
    "# Input parameters\n",
    "locations = {'regionN', 'regionS'}\n",
    "commodityUnitDict = {'electricity': r'GW$_{el}$', 'naturalGas': r'GW$_{CH_{4},LHV}$',\n",
    "                     'CO2': r'Mio. t$_{CO_2}$/h'}\n",
    "commodities = {'electricity', 'naturalGas', 'CO2'}\n",
    "numberOfTimeSteps, hoursPerTimeStep = 8760, 1\n",
    "costUnit, lengthUnit = '1e6 Euro', 'km'\n",
    "\n",
    "# Code\n",
    "esM = fn.EnergySystemModel(locations=locations, commodities=commodities,\n",
    "    numberOfTimeSteps=numberOfTimeSteps, commodityUnitsDict=commodityUnitDict,\n",
    "    hoursPerTimeStep=hoursPerTimeStep, costUnit=costUnit, lengthUnit=lengthUnit, verboseLogLevel=0)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Add source components\n",
    "\n",
    "Source components generate commodities across the energy system's virtual boundaries."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "# Input parameters\n",
    "name, commodity ='Wind turbines', 'electricity'\n",
    "hasCapacityVariable = True\n",
    "operationRateMax = pd.DataFrame([[np.random.beta(a=2,b=7.5),np.random.beta(a=2,b=9)]\n",
    "                                  for t in range(8760)],\n",
    "                                index=range(8760), columns=['regionN', 'regionS']).round(6)\n",
    "capacityMax = pd.Series([400, 200], index=['regionN', 'regionS'])\n",
    "investPerCapacity, opexPerCapacity = 1200, 1200*0.02\n",
    "interestRate, economicLifetime = 0.08, 20\n",
    "\n",
    "# If data should be read from an excel file:\n",
    "writer = pd.ExcelWriter('windTurbineProfile.xlsx') # writes data to an excel file\n",
    "operationRateMax.to_excel(writer)                  # (not required if excel file\n",
    "writer.save()                                      #  already exists)\n",
    "operationRateMax = pd.read_excel('windTurbineProfile.xlsx', index_col=0) # reads an excel file located in \n",
    "                                                            # the current working directory\n",
    "    \n",
    "# Code\n",
    "esM.add(fn.Source(esM=esM, name=name, commodity=commodity, hasCapacityVariable=hasCapacityVariable,\n",
    "    operationRateMax=operationRateMax, capacityMax=capacityMax, investPerCapacity=investPerCapacity,\n",
    "    opexPerCapacity=opexPerCapacity, interestRate=interestRate, economicLifetime=economicLifetime))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "# Input parameters\n",
    "name, commodity ='PV', 'electricity'\n",
    "hasCapacityVariable = True\n",
    "dailyProfileSimple = [0,0,0,0,0,0,0,0.05,0.15,0.2,0.4,0.8,0.7,0.4,0.2,0.15,0.05,0,0,0,0,0,0,0]\n",
    "operationRateMax = pd.DataFrame([[u,u] for day in range(365) for u in dailyProfileSimple],\n",
    "                                index=range(8760), columns=['regionN', 'regionS'])\n",
    "capacityMax = pd.Series([100, 100], index=['regionN', 'regionS'])\n",
    "investPerCapacity, opexPerCapacity = 800, 800*0.02\n",
    "interestRate, economicLifetime = 0.08, 25\n",
    "\n",
    "# If data should be read from an excel file:\n",
    "writer = pd.ExcelWriter('PV_Profile.xlsx') # writes data to an excel file\n",
    "operationRateMax.to_excel(writer)                  # (not required if excel file\n",
    "writer.save()                                      #  already exists)\n",
    "operationRateMax = pd.read_excel('PV_Profile.xlsx', index_col=0) # reads an excel file located in \n",
    "                                                            # the current working directory\n",
    "\n",
    "# Code\n",
    "esM.add(fn.Source(esM=esM, name=name, commodity=commodity, hasCapacityVariable=hasCapacityVariable,\n",
    "    operationRateMax=operationRateMax, capacityMax=capacityMax, investPerCapacity=investPerCapacity,\n",
    "    opexPerCapacity=opexPerCapacity, interestRate=interestRate, economicLifetime=economicLifetime))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Input parameters\n",
    "name, commodity ='Natural gas import', 'naturalGas'\n",
    "hasCapacityVariable = False\n",
    "commodityCost = 0.03\n",
    "\n",
    "# Code\n",
    "esM.add(fn.Source(esM=esM, name=name, commodity=commodity, hasCapacityVariable=hasCapacityVariable,\n",
    "    commodityCost=commodityCost))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##  Add conversion components\n",
    "\n",
    "Conversion components convert m commodities into n other commodities."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Input parameters\n",
    "name, physicalUnit = 'Gas power plants', r'GW$_{el}$'\n",
    "commodityConversionFactors = {'electricity':1, 'naturalGas':-1/0.63, 'CO2':201*1e-6/0.63}\n",
    "hasCapacityVariable=True\n",
    "investPerCapacity, opexPerCapacity = 650, 650*0.03\n",
    "interestRate, economicLifetime = 0.08, 30\n",
    "\n",
    "# Code\n",
    "esM.add(fn.Conversion(esM=esM, name=name, physicalUnit=physicalUnit,\n",
    "    commodityConversionFactors=commodityConversionFactors, hasCapacityVariable=hasCapacityVariable,\n",
    "    investPerCapacity=investPerCapacity, opexPerCapacity=opexPerCapacity, \n",
    "    interestRate=interestRate, economicLifetime=economicLifetime))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Add storage components\n",
    "\n",
    "Storage components can store commodities across time steps.\n",
    "\n",
    "The self discharge of a storage technology is described in FINE in percent per hour. If the literature value is given in percent per month, e.g. 3%/month, the self discharge per hours is obtained using the equation (1-$\\text{selfDischarge}_\\text{hour})^{30*24\\text{h}} = 1-\\text{selfDischarge}_\\text{month}$."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Input parameters\n",
    "name, commodity = 'Batteries', 'electricity'\n",
    "hasCapacityVariable=True\n",
    "chargeEfficiency, dischargeEfficiency, selfDischarge = 0.95, 0.95, 1-(1-0.03)**(1/(30*24))\n",
    "chargeRate, dischargeRate = 1, 1\n",
    "investPerCapacity, opexPerCapacity = 150, 150*0.01\n",
    "interestRate, economicLifetime, cyclicLifetime = 0.08, 22, 12000\n",
    "\n",
    "# Code\n",
    "esM.add(fn.Storage(esM=esM, name=name, commodity=commodity, hasCapacityVariable=hasCapacityVariable,\n",
    "    chargeEfficiency=chargeEfficiency, cyclicLifetime=cyclicLifetime,\n",
    "    dischargeEfficiency=dischargeEfficiency, selfDischarge=selfDischarge, chargeRate=chargeRate,\n",
    "    dischargeRate=dischargeRate, investPerCapacity=investPerCapacity,\n",
    "    opexPerCapacity=opexPerCapacity, interestRate=interestRate, economicLifetime=economicLifetime))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Add transmission components\n",
    "\n",
    "Transmission components transmit commodities between regions."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Input parameters\n",
    "name, commodity ='AC cables', 'electricity'\n",
    "hasCapacityVariable = True\n",
    "capacityFix = pd.DataFrame([[0, 30], [30, 0]], columns=['regionN', 'regionS'],\n",
    "    index=['regionN', 'regionS'])\n",
    "distances = pd.DataFrame([[0, 400], [400, 0]], columns=['regionN', 'regionS'],\n",
    "    index=['regionN', 'regionS'])\n",
    "losses=0.0001\n",
    "\n",
    "# Code\n",
    "esM.add(fn.Transmission(esM=esM, name=name, commodity=commodity,\n",
    "    hasCapacityVariable=hasCapacityVariable, capacityFix=capacityFix,\n",
    "    distances=distances, losses=losses))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>regionN</th>\n",
       "      <th>regionS</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>regionN</th>\n",
       "      <td>0</td>\n",
       "      <td>400</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>regionS</th>\n",
       "      <td>400</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "         regionN  regionS\n",
       "regionN        0      400\n",
       "regionS      400        0"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "distances"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Add sink components\n",
    "\n",
    "Sinks remove commodities across the energy system´s virtual boundaries."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "code_folding": [],
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "# Input parameters\n",
    "name, commodity ='Electricity demand', 'electricity',\n",
    "hasCapacityVariable = False\n",
    "dailyProfileSimple = [0.6,0.6,0.6,0.6,0.6,0.7,0.9,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0.9,0.8]\n",
    "operationRateFix = pd.DataFrame([[(u+0.1*np.random.rand())*25,(u+0.1*np.random.rand())*40]\n",
    "                                 for day in range(365) for u in dailyProfileSimple],\n",
    "                                index=range(8760), columns=['regionN', 'regionS']).round(2)\n",
    "\n",
    "# If data should be read from an excel file:\n",
    "writer = pd.ExcelWriter('demandProfile.xlsx') # writes data to an excel file\n",
    "operationRateFix.to_excel(writer)                  # (not required if excel file\n",
    "writer.save()                                      #  already exists)\n",
    "operationRateFix = pd.read_excel('demandProfile.xlsx', index_col=0) # reads an excel file located in \n",
    "                                                            # the current working directory\n",
    "\n",
    "# Code\n",
    "esM.add(fn.Sink(esM=esM, name=name, commodity=commodity, hasCapacityVariable=hasCapacityVariable,\n",
    "    operationRateFix=operationRateFix))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Input parameters\n",
    "name, commodity ='CO2 to enviroment', 'CO2',\n",
    "hasCapacityVariable=False\n",
    "commodityLimitID, yearlyLimit ='CO2 limit', 366*(1-0.8)\n",
    "\n",
    "# Code\n",
    "if yearlyLimit > 0:\n",
    "    esM.add(fn.Sink(esM=esM, name=name, commodity=commodity,\n",
    "        hasCapacityVariable=hasCapacityVariable, commodityLimitID=commodityLimitID,\n",
    "        yearlyLimit=yearlyLimit))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Optimize energy system model"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "All components are now added to the model and the model can be optimized. If the computational complexity of the optimization should be reduced, the time series data of the specified components can be clustered before the optimization and the parameter timeSeriesAggregation is set to True in the optimize call."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Clustering time series data with 30 typical periods and 24 time steps per period...\n",
      "\t\t(1.0917 sec)\n",
      "\n"
     ]
    }
   ],
   "source": [
    "# Input parameters\n",
    "numberOfTypicalPeriods=30\n",
    "\n",
    "# Code\n",
    "esM.cluster(numberOfTypicalPeriods=numberOfTypicalPeriods)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Time series aggregation specifications:\n",
      "Number of typical periods:30, number of time steps per periods:24\n",
      "\n",
      "Declaring sets, variables and constraints for SourceSinkModel\n",
      "\tdeclaring sets... \n",
      "\tdeclaring variables... \n",
      "\tdeclaring constraints... \n",
      "\t\t(1.1259 sec)\n",
      "\n",
      "Declaring sets, variables and constraints for ConversionModel\n",
      "\tdeclaring sets... \n",
      "\tdeclaring variables... \n",
      "\tdeclaring constraints... \n",
      "\t\t(0.0380 sec)\n",
      "\n",
      "Declaring sets, variables and constraints for StorageModel\n",
      "\tdeclaring sets... \n",
      "\tdeclaring variables... \n",
      "\tdeclaring constraints... \n",
      "\t\t(0.3400 sec)\n",
      "\n",
      "Declaring sets, variables and constraints for TransmissionModel\n",
      "\tdeclaring sets... \n",
      "\tdeclaring variables... \n",
      "\tdeclaring constraints... \n",
      "\t\t(0.0400 sec)\n",
      "\n",
      "Declaring shared potential constraint...\n",
      "\t\t(0.0000 sec)\n",
      "\n",
      "Declaring commodity balances...\n",
      "\t\t(0.3400 sec)\n",
      "\n",
      "Declaring objective function...\n",
      "\t\t(0.1300 sec)\n",
      "\n",
      "GLPSOL: GLPK LP/MIP Solver, v4.65\n",
      "Parameter(s) specified in the command line:\n",
      " --write C:\\Users\\there\\AppData\\Local\\Temp\\tmp19slz48x.glpk.raw --wglp C:\\Users\\there\\AppData\\Local\\Temp\\tmpicfjux5v.glpk.glp\n",
      " --cpxlp C:\\Users\\there\\AppData\\Local\\Temp\\tmp5dzc9kbr.pyomo.lp\n",
      "Reading problem data from 'C:\\Users\\there\\AppData\\Local\\Temp\\tmp5dzc9kbr.pyomo.lp'...\n",
      "20990 rows, 15333 columns, 56933 non-zeros\n",
      "136691 lines were read\n",
      "Writing problem data to 'C:\\Users\\there\\AppData\\Local\\Temp\\tmpicfjux5v.glpk.glp'...\n",
      "110757 lines were written\n",
      "GLPK Simplex Optimizer, v4.65\n",
      "20990 rows, 15333 columns, 56933 non-zeros\n",
      "Preprocessing...\n",
      "17075 rows, 11540 columns, 47666 non-zeros\n",
      "Scaling...\n",
      " A: min|aij| =  3.190e-04  max|aij| =  5.455e+02  ratio =  1.710e+06\n",
      "GM: min|aij| =  2.723e-01  max|aij| =  3.672e+00  ratio =  1.348e+01\n",
      "EQ: min|aij| =  7.416e-02  max|aij| =  1.000e+00  ratio =  1.348e+01\n",
      "Constructing initial basis...\n",
      "Size of triangular part is 17073\n",
      "      0: obj =   0.000000000e+00 inf =   1.470e+04 (1440)\n",
      "   1452: obj =   9.701297622e+04 inf =   0.000e+00 (0) 14\n",
      "Perturbing LP to avoid instability [3974]...\n",
      "*  7668: obj =   4.028123286e+04 inf =   4.232e-06 (1687) 51\n",
      "Removing LP perturbation [11351]...\n",
      "* 11351: obj =   3.982873298e+04 inf =   3.353e-10 (0) 33\n",
      "OPTIMAL LP SOLUTION FOUND\n",
      "Time used:   9.1 secs\n",
      "Memory used: 23.6 Mb (24791713 bytes)\n",
      "Writing basic solution to 'C:\\Users\\there\\AppData\\Local\\Temp\\tmp19slz48x.glpk.raw'...\n",
      "36332 lines were written\n",
      "\n",
      "Status: ok\n",
      "Termination condition: optimal\n",
      "Statistics: \n",
      "  Branch and bound: \n",
      "    Number of bounded subproblems: 0\n",
      "    Number of created subproblems: 0\n",
      "Error rc: 0\n",
      "Time: 9.428424596786499\n",
      "\n",
      "\n",
      "Name: unknown\n",
      "Lower bound: 39828.7329832427\n",
      "Upper bound: 39828.7329832427\n",
      "Number of objectives: 1\n",
      "Number of constraints: 20990\n",
      "Number of variables: 15333\n",
      "Number of nonzeros: 56933\n",
      "Sense: minimize\n",
      "\n",
      "Solve time: 10.738036632537842 sec.\n",
      "\n",
      "Processing optimization output...\n",
      "for SourceSinkModel ...    (0.7979sec)\n",
      "for ConversionModel ...    (0.4019sec)\n",
      "for StorageModel ...       (1.8520sec)\n",
      "for TransmissionModel ...  (0.8040sec)\n",
      "\t\t(3.8557 sec)\n",
      "\n"
     ]
    }
   ],
   "source": [
    "# Input parameters\n",
    "timeSeriesAggregation=True\n",
    "solver='glpk'\n",
    "\n",
    "# Code\n",
    "esM.optimize(timeSeriesAggregation=timeSeriesAggregation, solver=solver)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Output of selected results\n",
    "\n",
    "For the assessment of the optimization result, several result output functions are available. They can be categorized into output in form of tables, geo-referenced output visualization and the full time series visualization.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Create a regional shape file and visualize it\n",
    "\n",
    "Information on the geometrical shape of the investigated regions can either be downloaded from a website (e.g. from https://gadm.org/) or manually created. In this notebook, the geometries are manually created."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 15296 characters]\n",
      "text/plain": [
       "<Figure size 432x432 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Create two circles, representing the two regions, and store their geometries in a shape file\n",
    "shpRegionS = shp.geometry.Point(0.5,0.5).buffer(0.5)\n",
    "shpRegionN = shp.geometry.Point(0.5,1.5).buffer(0.5)\n",
    "regionsGdf = gpd.GeoDataFrame({'geometry':[shpRegionN,shpRegionS],\n",
    "                               'regionName':['regionN','regionS']},\n",
    "                              index=['regionN','regionS'], crs='epsg:3035')\n",
    "regionsGdf.to_file('regions.shp')\n",
    "\n",
    "# Create a line, representing the connection between the two regions, and store its geometry in a\n",
    "# shape file\n",
    "lines = shp.geometry.LineString([(0.5,0.5),(0.5,1.5)])\n",
    "linesGdf = gpd.GeoDataFrame({'geometry':[lines, lines],'loc0':['regionN','regionS'],\n",
    "                             'loc1':['regionS','regionN']},\n",
    "                            index=['regionN_regionS','regionS_regionN'], crs='epsg:3035')\n",
    "linesGdf.to_file('lines.shp')\n",
    "\n",
    "# Visualize the geometric representation of the two regions\n",
    "fig, ax = fn.plotLocations('regions.shp', indexColumn='regionName', plotLocNames=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Display optimization summaries\n",
    "\n",
    "For each modeling class, an optimization summary can be stored and displayed. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th>regionN</th>\n",
       "      <th>regionS</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Component</th>\n",
       "      <th>Property</th>\n",
       "      <th>Unit</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>CO2 to enviroment</th>\n",
       "      <th>operation</th>\n",
       "      <th>[Mio. t$_{CO_2}$/h*h/a]</th>\n",
       "      <td>2.86345</td>\n",
       "      <td>70.3366</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Electricity demand</th>\n",
       "      <th>operation</th>\n",
       "      <th>[GW$_{el}$*h/a]</th>\n",
       "      <td>205208</td>\n",
       "      <td>328596</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"3\" valign=\"top\">Natural gas import</th>\n",
       "      <th>TAC</th>\n",
       "      <th>[1e6 Euro/a]</th>\n",
       "      <td>427.381</td>\n",
       "      <td>10498</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>commodCosts</th>\n",
       "      <th>[1e6 Euro/a]</th>\n",
       "      <td>427.381</td>\n",
       "      <td>10498</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>operation</th>\n",
       "      <th>[GW$_{CH_{4},LHV}$*h/a]</th>\n",
       "      <td>14246</td>\n",
       "      <td>349933</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"6\" valign=\"top\">PV</th>\n",
       "      <th>TAC</th>\n",
       "      <th>[1e6 Euro/a]</th>\n",
       "      <td>0</td>\n",
       "      <td>2635.28</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>capacity</th>\n",
       "      <th>[GW$_{el}$]</th>\n",
       "      <td>0</td>\n",
       "      <td>28.9772</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>capexCap</th>\n",
       "      <th>[1e6 Euro/a]</th>\n",
       "      <td>0</td>\n",
       "      <td>2171.64</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>invest</th>\n",
       "      <th>[1e6 Euro]</th>\n",
       "      <td>0</td>\n",
       "      <td>23181.8</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>operation</th>\n",
       "      <th>[GW$_{el}$*h/a]</th>\n",
       "      <td>0</td>\n",
       "      <td>32787.7</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>opexCap</th>\n",
       "      <th>[1e6 Euro/a]</th>\n",
       "      <td>0</td>\n",
       "      <td>463.636</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"6\" valign=\"top\">Wind turbines</th>\n",
       "      <th>TAC</th>\n",
       "      <th>[1e6 Euro/a]</th>\n",
       "      <td>22022.8</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>capacity</th>\n",
       "      <th>[GW$_{el}$]</th>\n",
       "      <td>150.611</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>capexCap</th>\n",
       "      <th>[1e6 Euro/a]</th>\n",
       "      <td>18408.1</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>invest</th>\n",
       "      <th>[1e6 Euro]</th>\n",
       "      <td>180734</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>operation</th>\n",
       "      <th>[GW$_{el}$*h/a]</th>\n",
       "      <td>277569</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>opexCap</th>\n",
       "      <th>[1e6 Euro/a]</th>\n",
       "      <td>3614.68</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                                                        regionN  regionS\n",
       "Component          Property    Unit                                     \n",
       "CO2 to enviroment  operation   [Mio. t$_{CO_2}$/h*h/a]  2.86345  70.3366\n",
       "Electricity demand operation   [GW$_{el}$*h/a]           205208   328596\n",
       "Natural gas import TAC         [1e6 Euro/a]             427.381    10498\n",
       "                   commodCosts [1e6 Euro/a]             427.381    10498\n",
       "                   operation   [GW$_{CH_{4},LHV}$*h/a]    14246   349933\n",
       "PV                 TAC         [1e6 Euro/a]                   0  2635.28\n",
       "                   capacity    [GW$_{el}$]                    0  28.9772\n",
       "                   capexCap    [1e6 Euro/a]                   0  2171.64\n",
       "                   invest      [1e6 Euro]                     0  23181.8\n",
       "                   operation   [GW$_{el}$*h/a]                0  32787.7\n",
       "                   opexCap     [1e6 Euro/a]                   0  463.636\n",
       "Wind turbines      TAC         [1e6 Euro/a]             22022.8        0\n",
       "                   capacity    [GW$_{el}$]              150.611        0\n",
       "                   capexCap    [1e6 Euro/a]             18408.1        0\n",
       "                   invest      [1e6 Euro]                180734        0\n",
       "                   operation   [GW$_{el}$*h/a]           277569        0\n",
       "                   opexCap     [1e6 Euro/a]             3614.68        0"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "srcSnkSummary = esM.getOptimizationSummary(\"SourceSinkModel\", outputLevel=1)\n",
    "display(esM.getOptimizationSummary(\"SourceSinkModel\", outputLevel=2))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th>regionN</th>\n",
       "      <th>regionS</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Component</th>\n",
       "      <th>Property</th>\n",
       "      <th>Unit</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th rowspan=\"6\" valign=\"top\">Gas power plants</th>\n",
       "      <th>TAC</th>\n",
       "      <th>[1e6 Euro/a]</th>\n",
       "      <td>220.614</td>\n",
       "      <td>3139.39</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>capacity</th>\n",
       "      <th>[GW$_{el}$]</th>\n",
       "      <td>2.85629</td>\n",
       "      <td>40.6457</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>capexCap</th>\n",
       "      <th>[1e6 Euro/a]</th>\n",
       "      <td>164.916</td>\n",
       "      <td>2346.8</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>invest</th>\n",
       "      <th>[1e6 Euro]</th>\n",
       "      <td>1856.59</td>\n",
       "      <td>26419.7</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>operation</th>\n",
       "      <th>[GW$_{el}$*h/a]</th>\n",
       "      <td>8974.99</td>\n",
       "      <td>220458</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>opexCap</th>\n",
       "      <th>[1e6 Euro/a]</th>\n",
       "      <td>55.6977</td>\n",
       "      <td>792.591</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                                            regionN  regionS\n",
       "Component        Property  Unit                             \n",
       "Gas power plants TAC       [1e6 Euro/a]     220.614  3139.39\n",
       "                 capacity  [GW$_{el}$]      2.85629  40.6457\n",
       "                 capexCap  [1e6 Euro/a]     164.916   2346.8\n",
       "                 invest    [1e6 Euro]       1856.59  26419.7\n",
       "                 operation [GW$_{el}$*h/a]  8974.99   220458\n",
       "                 opexCap   [1e6 Euro/a]     55.6977  792.591"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "convSummary = esM.getOptimizationSummary(\"ConversionModel\", outputLevel=1)\n",
    "display(esM.getOptimizationSummary(\"ConversionModel\", outputLevel=2))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th>regionN</th>\n",
       "      <th>regionS</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Component</th>\n",
       "      <th>Property</th>\n",
       "      <th>Unit</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th rowspan=\"7\" valign=\"top\">Batteries</th>\n",
       "      <th>TAC</th>\n",
       "      <th>[1e6 Euro/a]</th>\n",
       "      <td>825.344</td>\n",
       "      <td>59.9289</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>capacity</th>\n",
       "      <th>[GW$_{el}$*h]</th>\n",
       "      <td>50.932</td>\n",
       "      <td>3.69822</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>capexCap</th>\n",
       "      <th>[1e6 Euro/a]</th>\n",
       "      <td>748.946</td>\n",
       "      <td>54.3816</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>invest</th>\n",
       "      <th>[1e6 Euro]</th>\n",
       "      <td>7639.8</td>\n",
       "      <td>554.733</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>operationCharge</th>\n",
       "      <th>[GW$_{el}$*h/a]</th>\n",
       "      <td>22394</td>\n",
       "      <td>793.176</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>operationDischarge</th>\n",
       "      <th>[GW$_{el}$*h/a]</th>\n",
       "      <td>20204.1</td>\n",
       "      <td>715.588</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>opexCap</th>\n",
       "      <th>[1e6 Euro/a]</th>\n",
       "      <td>76.398</td>\n",
       "      <td>5.54733</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                                              regionN  regionS\n",
       "Component Property           Unit                             \n",
       "Batteries TAC                [1e6 Euro/a]     825.344  59.9289\n",
       "          capacity           [GW$_{el}$*h]     50.932  3.69822\n",
       "          capexCap           [1e6 Euro/a]     748.946  54.3816\n",
       "          invest             [1e6 Euro]        7639.8  554.733\n",
       "          operationCharge    [GW$_{el}$*h/a]    22394  793.176\n",
       "          operationDischarge [GW$_{el}$*h/a]  20204.1  715.588\n",
       "          opexCap            [1e6 Euro/a]      76.398  5.54733"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "storSummary = esM.getOptimizationSummary(\"StorageModel\", outputLevel=1)\n",
    "display(esM.getOptimizationSummary(\"StorageModel\", outputLevel=2))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th>regionN</th>\n",
       "      <th>regionS</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Component</th>\n",
       "      <th>Property</th>\n",
       "      <th>Unit</th>\n",
       "      <th>LocationIn</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th rowspan=\"4\" valign=\"top\">AC cables</th>\n",
       "      <th rowspan=\"2\" valign=\"top\">capacity</th>\n",
       "      <th rowspan=\"2\" valign=\"top\">[GW$_{el}$]</th>\n",
       "      <th>regionN</th>\n",
       "      <td>NaN</td>\n",
       "      <td>30</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>regionS</th>\n",
       "      <td>30</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th rowspan=\"2\" valign=\"top\">operation</th>\n",
       "      <th rowspan=\"2\" valign=\"top\">[GW$_{el}$*h/a]</th>\n",
       "      <th>regionN</th>\n",
       "      <td>NaN</td>\n",
       "      <td>85907.2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>regionS</th>\n",
       "      <td>7042.58</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                                                regionN  regionS\n",
       "Component Property  Unit            LocationIn                  \n",
       "AC cables capacity  [GW$_{el}$]     regionN         NaN       30\n",
       "                                    regionS          30      NaN\n",
       "          operation [GW$_{el}$*h/a] regionN         NaN  85907.2\n",
       "                                    regionS     7042.58      NaN"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "transSummary = esM.getOptimizationSummary(\"TransmissionModel\", outputLevel=1)\n",
    "display(esM.getOptimizationSummary(\"TransmissionModel\", outputLevel=2))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Display regional and operational plots\n",
    "\n",
    "Georeferenced plots as well as plots representing time series can be displayed for each component."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Wind turbines"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 14276 characters]\n",
      "text/plain": [
       "<Figure size 288x288 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 40024 characters]\n",
      "text/plain": [
       "<Figure size 360x216 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# If wind turbines are built, their capacities are displayed in a geo-referenced plot\n",
    "if srcSnkSummary.loc[('Wind turbines','capacity','[GW$_{el}$]')].sum() > 0:\n",
    "    fig, ax = fn.plotLocationalColorMap(esM, 'Wind turbines', 'regions.shp', 'regionName',\n",
    "        perArea=False, zlabel='Capacity\\n[GW]\\n', figsize=(4,4))\n",
    "else:\n",
    "    print('No wind turbines built.')\n",
    "\n",
    "# If wind turbines are built in regionN, their operation is displayed as heatmap\n",
    "if srcSnkSummary.loc[('Wind turbines','capacity','[GW$_{el}$]'),'regionN'] > 0:\n",
    "    fig, ax = fn.plotOperationColorMap(esM, 'Wind turbines', 'regionN', figsize=(5,3), \n",
    "        xlabel='Day of the year', ylabel='Hour of the day', zlabel='Operation\\nin regionN\\n[GW]')\n",
    "\n",
    "# If wind turbines are built in regionS, their operation is displayed as heatmap\n",
    "if srcSnkSummary.loc[('Wind turbines','capacity','[GW$_{el}$]'),'regionS'] > 0:\n",
    "    fig, ax = fn.plotOperationColorMap(esM, 'Wind turbines', 'regionS', figsize=(5,3), \n",
    "        xlabel='Day of the year', ylabel='Hour of the Day', zlabel='Operation\\nin regionS\\n[GW]', orientation='vertical')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### PV systems"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 13844 characters]\n",
      "text/plain": [
       "<Figure size 288x288 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 10884 characters]\n",
      "text/plain": [
       "<Figure size 360x216 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# If PV systems are built, their capacities are displayed in a geo-referenced plot\n",
    "if srcSnkSummary.loc[('PV','capacity','[GW$_{el}$]')].sum() > 0:\n",
    "    fig, ax = fn.plotLocationalColorMap(esM, 'PV', 'regions.shp', 'regionName', perArea=False,\n",
    "        zlabel='Capacity\\n[GW]\\n', figsize=(4,4))\n",
    "else:\n",
    "    print('No PV systems built.')\n",
    "\n",
    "# If PV systems are built in regionS, their operation is displayed as heatmap\n",
    "if srcSnkSummary.loc[('PV','capacity','[GW$_{el}$]'),'regionN'] > 0:\n",
    "    fig, ax = fn.plotOperationColorMap(esM, 'PV', 'regionN', figsize=(5,3), \n",
    "        xlabel='Day of the year', ylabel='Hour of the day', zlabel='Operation\\nin regionN\\n[GW]')\n",
    "\n",
    "# If PV systems are built in regionS, their operation is displayed as heatmap\n",
    "if srcSnkSummary.loc[('PV','capacity','[GW$_{el}$]'),'regionS'] > 0:\n",
    "    fig, ax = fn.plotOperationColorMap(esM, 'PV', 'regionS', figsize=(5,3), \n",
    "        xlabel='Day of the year', ylabel='Hour of the day', zlabel='Operation\\nin regionS\\n[GW]', orientation='vertical')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Gas power plants"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 14276 characters]\n",
      "text/plain": [
       "<Figure size 288x288 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 15072 characters]\n",
      "text/plain": [
       "<Figure size 360x216 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 30448 characters]\n",
      "text/plain": [
       "<Figure size 360x216 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# If CCGT plants are built, their capacities are displayed in a geo-referenced plot\n",
    "if convSummary.loc[('Gas power plants','capacity','[GW$_{el}$]')].sum() > 0:\n",
    "    fig, ax = fn.plotLocationalColorMap(esM, 'Gas power plants', 'regions.shp', 'regionName',\n",
    "        perArea=False, zlabel='Capacity\\n[GW]\\n', figsize=(4,4))\n",
    "else:\n",
    "    print('No CCGT plants built.')\n",
    "\n",
    "# If CCGT plants are built in regionS, their operation is displayed as heatmap\n",
    "if convSummary.loc[('Gas power plants','capacity','[GW$_{el}$]'),'regionN'] > 0:\n",
    "    fig, ax = fn.plotOperationColorMap(esM, 'Gas power plants', 'regionN', figsize=(5,3), \n",
    "        xlabel='Day of the year', ylabel='Hour of the day', zlabel='Operation\\nin regionN\\n[GW]', orientation='vertical')\n",
    "\n",
    "# If CCGT plants are built in regionS, their operation is displayed as heatmap\n",
    "if convSummary.loc[('Gas power plants','capacity','[GW$_{el}$]'),'regionS'] > 0:\n",
    "    fig, ax = fn.plotOperationColorMap(esM, 'Gas power plants', 'regionS', figsize=(5,3), \n",
    "        xlabel='Day of the year', ylabel='Hour of the day', zlabel='Operation\\nin regionS\\n[GW]', orientation='vertical')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Batteries"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {
    "code_folding": [],
    "scrolled": false
   },
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 14420 characters]\n",
      "text/plain": [
       "<Figure size 288x288 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 20148 characters]\n",
      "text/plain": [
       "<Figure size 360x216 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 12488 characters]\n",
      "text/plain": [
       "<Figure size 360x216 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# If batteries are built, their capacities are displayed in a geo-referenced plot\n",
    "if storSummary.loc[('Batteries','capacity','[GW$_{el}$*h]')].sum() > 0:\n",
    "    fig, ax = fn.plotLocationalColorMap(esM, 'Batteries', 'regions.shp', 'regionName',\n",
    "        perArea=False, zlabel='Capacity\\n[GWh]\\n', figsize=(4,4))\n",
    "else:\n",
    "    print('No batteries built.')\n",
    "    \n",
    "# If batteries are built in regionS, their storage inventory is displayed as heatmap\n",
    "if storSummary.loc[('Batteries','capacity','[GW$_{el}$*h]'),'regionN'] > 0:\n",
    "    fig, ax = fn.plotOperationColorMap(esM, 'Batteries', 'regionN', figsize=(5,3),\n",
    "        xlabel='Day of the year', ylabel='Hour of the day',\n",
    "        zlabel='State of charge\\nin regionN\\n[GW]',\n",
    "        variableName='stateOfChargeOperationVariablesOptimum', orientation='vertical')\n",
    "\n",
    "# If batteries are built in regionS, their storage inventory is displayed as heatmap\n",
    "if storSummary.loc[('Batteries','capacity','[GW$_{el}$*h]'),'regionS'] > 0:\n",
    "    fig, ax = fn.plotOperationColorMap(esM, 'Batteries', 'regionS', figsize=(5,3),\n",
    "        xlabel='Day of the year', ylabel='Hour of the day',\n",
    "        zlabel='State of charge\\nin regionS\\n[GW]',\n",
    "        variableName='stateOfChargeOperationVariablesOptimum', orientation='vertical')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### AC cables"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 16320 characters]\n",
      "text/plain": [
       "<Figure size 432x432 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# The built AC cable capacities are displayed\n",
    "fig, ax = fn.plotLocations('regions.shp', indexColumn='regionName')   \n",
    "fig, ax = fn.plotTransmission(esM, 'AC cables', 'lines.shp', loc0='loc0', loc1='loc1',\n",
    "    fig=fig, ax=ax, cbHeight=0.4)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Electricity demand"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 25620 characters]\n",
      "text/plain": [
       "<Figure size 360x216 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "[encoded data, 26392 characters]\n",
      "text/plain": [
       "<Figure size 360x216 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# The electricity demand time series in regionN is displayed\n",
    "fig, ax = fn.plotOperationColorMap(esM, 'Electricity demand', 'regionN', figsize=(5,3), \n",
    "    xlabel='Day of the year', ylabel='Hour of the day', zlabel='Demand\\nin regionN\\n[GW]', orientation='vertical')\n",
    "\n",
    "# The electricity demand time series in regionS is displayed\n",
    "fig, ax = fn.plotOperationColorMap(esM, 'Electricity demand', 'regionS', figsize=(5,3), \n",
    "    xlabel='Day of the year', ylabel='Hour of the day', zlabel='Demand\\nin regionS\\n[GW]', orientation='vertical')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.9"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {
    "height": "431px",
    "width": "510px"
   },
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {
    "height": "calc(100% - 180px)",
    "left": "10px",
    "top": "150px",
    "width": "399px"
   },
   "toc_section_display": true,
   "toc_window_display": true
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
