2024-05-04 09:59:27 +02:00
|
|
|
{
|
|
|
|
"cells": [
|
|
|
|
{
|
|
|
|
"cell_type": "code",
|
2024-05-08 16:07:14 +02:00
|
|
|
"execution_count": 1,
|
2024-05-06 19:23:42 +02:00
|
|
|
"metadata": {},
|
|
|
|
"outputs": [],
|
|
|
|
"source": [
|
|
|
|
"import os\n",
|
|
|
|
"import glob\n",
|
|
|
|
"import shutil\n",
|
|
|
|
"\n",
|
|
|
|
"def clear_folder_make_ess_pv(folder_path):\n",
|
2024-05-07 20:20:09 +02:00
|
|
|
" if os.path.isdir(folder_path):\n",
|
|
|
|
" shutil.rmtree(folder_path)\n",
|
2024-05-06 19:23:42 +02:00
|
|
|
" os.makedirs(folder_path)\n",
|
|
|
|
" os.makedirs(os.path.join(folder_path,'ess'))\n",
|
|
|
|
" os.makedirs(os.path.join(folder_path,'pv'))\n",
|
|
|
|
"\n",
|
|
|
|
"folder_path = 'plots'\n",
|
|
|
|
"clear_folder_make_ess_pv(folder_path)"
|
|
|
|
]
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"cell_type": "code",
|
2024-05-08 16:07:14 +02:00
|
|
|
"execution_count": 2,
|
2024-05-04 09:59:27 +02:00
|
|
|
"metadata": {},
|
2024-05-04 16:35:55 +02:00
|
|
|
"outputs": [],
|
2024-05-04 09:59:27 +02:00
|
|
|
"source": [
|
|
|
|
"import matplotlib.pyplot as plt\n",
|
|
|
|
"import seaborn as sns\n",
|
|
|
|
"import numpy as np\n",
|
|
|
|
"import pandas as pd\n",
|
|
|
|
"from EnergySystem import EnergySystem\n",
|
2024-05-07 20:20:09 +02:00
|
|
|
"from config import pv_config, grid_config, ess_config\n"
|
2024-05-06 19:23:42 +02:00
|
|
|
]
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"cell_type": "code",
|
2024-05-08 16:07:14 +02:00
|
|
|
"execution_count": 3,
|
2024-05-06 19:23:42 +02:00
|
|
|
"metadata": {},
|
2024-05-08 16:07:14 +02:00
|
|
|
"outputs": [
|
|
|
|
{
|
|
|
|
"name": "stdout",
|
|
|
|
"output_type": "stream",
|
|
|
|
"text": [
|
|
|
|
"Version 0.0.2\n"
|
|
|
|
]
|
|
|
|
}
|
|
|
|
],
|
2024-05-06 19:23:42 +02:00
|
|
|
"source": [
|
2024-05-07 10:27:45 +02:00
|
|
|
"import json\n",
|
|
|
|
"\n",
|
2024-05-08 09:39:56 +02:00
|
|
|
"print(\"Version 0.0.2\")\n",
|
|
|
|
"\n",
|
2024-05-07 10:27:45 +02:00
|
|
|
"with open('config.json', 'r') as f:\n",
|
|
|
|
" js_data = json.load(f)\n",
|
|
|
|
"\n",
|
2024-05-04 09:59:27 +02:00
|
|
|
"data = pd.read_csv('combined_data.csv')\n",
|
2024-05-07 10:27:45 +02:00
|
|
|
"time_interval = js_data[\"time_interval\"][\"numerator\"] / js_data[\"time_interval\"][\"denominator\"]\n",
|
|
|
|
"\n",
|
|
|
|
"pv_loss = js_data[\"pv\"][\"loss\"]\n",
|
|
|
|
"pv_cost_per_kW = js_data[\"pv\"][\"cost_per_kW\"]\n",
|
|
|
|
"pv_lifetime = js_data[\"pv\"][\"lifetime\"]\n",
|
2024-05-04 09:59:27 +02:00
|
|
|
"\n",
|
2024-05-07 10:27:45 +02:00
|
|
|
"ess_loss = js_data[\"ess\"][\"loss\"]\n",
|
|
|
|
"ess_cost_per_kW = js_data[\"ess\"][\"cost_per_kW\"]\n",
|
|
|
|
"ess_lifetime = js_data[\"ess\"][\"lifetime\"]\n",
|
2024-05-04 09:59:27 +02:00
|
|
|
"\n",
|
2024-05-07 10:27:45 +02:00
|
|
|
"grid_loss = js_data[\"grid\"][\"loss\"]\n",
|
|
|
|
"sell_price = js_data[\"grid\"][\"sell_price\"] #kWh\n",
|
|
|
|
"grid_capacity = js_data[\"grid\"][\"capacity\"] #kWh\n",
|
2024-05-04 09:59:27 +02:00
|
|
|
"\n",
|
2024-05-07 10:27:45 +02:00
|
|
|
"pv_begin = js_data[\"pv_capacities\"][\"begin\"]\n",
|
|
|
|
"pv_end = js_data[\"pv_capacities\"][\"end\"]\n",
|
|
|
|
"pv_groups = js_data[\"pv_capacities\"][\"groups\"]\n",
|
2024-05-04 09:59:27 +02:00
|
|
|
"\n",
|
2024-05-07 10:27:45 +02:00
|
|
|
"ess_begin = js_data[\"ess_capacities\"][\"begin\"]\n",
|
|
|
|
"ess_end = js_data[\"ess_capacities\"][\"end\"]\n",
|
|
|
|
"ess_groups = js_data[\"ess_capacities\"][\"groups\"]\n",
|
2024-05-07 20:20:09 +02:00
|
|
|
"\n",
|
|
|
|
"annot_unmet = js_data[\"annotated\"][\"unmet_prob\"]\n",
|
|
|
|
"annot_benefit = js_data[\"annotated\"][\"benefit\"]\n",
|
|
|
|
"annot_cost = js_data[\"annotated\"][\"cost\"]\n",
|
|
|
|
"\n",
|
|
|
|
"title_unmet = js_data[\"plot_title\"][\"unmet_prob\"]\n",
|
|
|
|
"title_cost = js_data[\"plot_title\"][\"cost\"]\n",
|
|
|
|
"title_benefit = js_data[\"plot_title\"][\"benefit\"]\n",
|
|
|
|
"\n",
|
|
|
|
"figure_size = (js_data[\"figure_size\"][\"length\"], js_data[\"figure_size\"][\"height\"])\n",
|
|
|
|
"\n",
|
2024-05-07 10:27:45 +02:00
|
|
|
"pv_capacities = np.linspace(pv_begin, pv_end, pv_groups)\n",
|
|
|
|
"ess_capacities = np.linspace(ess_begin, ess_end, ess_groups)\n",
|
2024-05-06 19:23:42 +02:00
|
|
|
"results = pd.DataFrame(index=pv_capacities, columns= ess_capacities)\n",
|
|
|
|
"affords = pd.DataFrame(index=pv_capacities, columns= ess_capacities)\n",
|
2024-05-07 10:27:45 +02:00
|
|
|
"costs = pd.DataFrame(index=pv_capacities, columns= ess_capacities)\n",
|
2024-05-06 19:23:42 +02:00
|
|
|
"overload_cnt = pd.DataFrame(index=pv_capacities, columns= ess_capacities)\n"
|
|
|
|
]
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"cell_type": "code",
|
2024-05-08 16:07:14 +02:00
|
|
|
"execution_count": 4,
|
2024-05-06 19:23:42 +02:00
|
|
|
"metadata": {},
|
|
|
|
"outputs": [],
|
|
|
|
"source": [
|
|
|
|
"hour_demand = []\n",
|
|
|
|
"for index, row in data.iterrows():\n",
|
|
|
|
" time = row['time']\n",
|
|
|
|
" demand = row['demand']\n",
|
|
|
|
" if time.endswith('00'):\n",
|
|
|
|
" hour_demand.append(demand)\n",
|
|
|
|
"plt.figure(figsize=(10,8))\n",
|
|
|
|
"plt.plot(hour_demand)\n",
|
|
|
|
"plt.ylabel('Demand Power / kW')\n",
|
|
|
|
"plt.savefig('plots/demand.png')\n",
|
|
|
|
"plt.close()"
|
|
|
|
]
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"cell_type": "code",
|
2024-05-08 16:07:14 +02:00
|
|
|
"execution_count": 5,
|
2024-05-06 19:23:42 +02:00
|
|
|
"metadata": {},
|
|
|
|
"outputs": [],
|
|
|
|
"source": [
|
|
|
|
"def cal_profit(es: EnergySystem, saved_money):\n",
|
|
|
|
" profit = saved_money - es.ess.get_cost_per_year() - es.pv.get_cost_per_year()\n",
|
|
|
|
" return profit"
|
|
|
|
]
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"cell_type": "code",
|
2024-05-08 16:07:14 +02:00
|
|
|
"execution_count": 6,
|
2024-05-06 19:23:42 +02:00
|
|
|
"metadata": {},
|
|
|
|
"outputs": [
|
|
|
|
{
|
|
|
|
"name": "stdout",
|
|
|
|
"output_type": "stream",
|
|
|
|
"text": [
|
2024-05-08 16:07:14 +02:00
|
|
|
"ess_capacity:0.0\n",
|
|
|
|
"pv_capacity:0.0\n"
|
|
|
|
]
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"name": "stderr",
|
|
|
|
"output_type": "stream",
|
|
|
|
"text": [
|
2024-05-10 00:11:34 +02:00
|
|
|
"/home/stud/hanzhang/simple-pv-simulator/EnergySystem.py:52: RuntimeWarning: invalid value encountered in scalar divide\n",
|
2024-05-08 16:07:14 +02:00
|
|
|
" soc = self.ess.storage / self.ess.capacity\n",
|
2024-05-10 00:11:34 +02:00
|
|
|
"/home/stud/hanzhang/simple-pv-simulator/EnergySystem.py:95: RuntimeWarning: invalid value encountered in scalar divide\n",
|
2024-05-08 16:07:14 +02:00
|
|
|
" log = f\"index: {index}, time: {time}, SoC:{self.ess.storage / self.ess.capacity}%, storage: {self.ess.storage}, pv_gen:{generated_pv_power}, power_demand: {factory_demand}, overload_cnt:{self.overload_cnt}, day:{int(index/96) + 1}\"\n",
|
2024-05-10 00:11:34 +02:00
|
|
|
"/home/stud/hanzhang/simple-pv-simulator/EnergySystem.py:49: RuntimeWarning: invalid value encountered in scalar divide\n",
|
2024-05-08 16:07:14 +02:00
|
|
|
" soc = self.ess.storage / self.ess.capacity\n",
|
2024-05-10 00:11:34 +02:00
|
|
|
"/home/stud/hanzhang/simple-pv-simulator/EnergySystem.py:120: RuntimeWarning: invalid value encountered in scalar divide\n",
|
2024-05-08 16:07:14 +02:00
|
|
|
" self.spring_week_soc.append(self.ess.storage / self.ess.capacity)\n"
|
|
|
|
]
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"name": "stdout",
|
|
|
|
"output_type": "stream",
|
|
|
|
"text": [
|
2024-05-09 13:15:53 +02:00
|
|
|
"pv_capacity:12500.0\n",
|
|
|
|
"pv_capacity:25000.0\n",
|
|
|
|
"pv_capacity:37500.0\n",
|
|
|
|
"pv_capacity:50000.0\n",
|
2024-05-08 16:07:14 +02:00
|
|
|
"ess_capacity:11111.111111111111\n",
|
2024-05-09 13:15:53 +02:00
|
|
|
"pv_capacity:0.0\n",
|
|
|
|
"pv_capacity:12500.0\n",
|
|
|
|
"pv_capacity:25000.0\n",
|
|
|
|
"pv_capacity:37500.0\n",
|
|
|
|
"pv_capacity:50000.0\n",
|
2024-05-08 16:07:14 +02:00
|
|
|
"ess_capacity:22222.222222222223\n",
|
2024-05-09 13:15:53 +02:00
|
|
|
"pv_capacity:0.0\n",
|
|
|
|
"pv_capacity:12500.0\n",
|
|
|
|
"pv_capacity:25000.0\n",
|
|
|
|
"pv_capacity:37500.0\n",
|
|
|
|
"pv_capacity:50000.0\n",
|
2024-05-08 16:07:14 +02:00
|
|
|
"ess_capacity:33333.333333333336\n",
|
2024-05-09 13:15:53 +02:00
|
|
|
"pv_capacity:0.0\n",
|
|
|
|
"pv_capacity:12500.0\n",
|
|
|
|
"pv_capacity:25000.0\n",
|
|
|
|
"pv_capacity:37500.0\n",
|
|
|
|
"pv_capacity:50000.0\n",
|
2024-05-08 16:07:14 +02:00
|
|
|
"ess_capacity:44444.444444444445\n",
|
2024-05-09 13:15:53 +02:00
|
|
|
"pv_capacity:0.0\n",
|
|
|
|
"pv_capacity:12500.0\n",
|
|
|
|
"pv_capacity:25000.0\n",
|
|
|
|
"pv_capacity:37500.0\n",
|
|
|
|
"pv_capacity:50000.0\n",
|
2024-05-08 16:07:14 +02:00
|
|
|
"ess_capacity:55555.555555555555\n",
|
2024-05-09 13:15:53 +02:00
|
|
|
"pv_capacity:0.0\n",
|
|
|
|
"pv_capacity:12500.0\n",
|
|
|
|
"pv_capacity:25000.0\n",
|
|
|
|
"pv_capacity:37500.0\n",
|
|
|
|
"pv_capacity:50000.0\n",
|
2024-05-08 16:07:14 +02:00
|
|
|
"ess_capacity:66666.66666666667\n",
|
2024-05-09 13:15:53 +02:00
|
|
|
"pv_capacity:0.0\n",
|
|
|
|
"pv_capacity:12500.0\n",
|
|
|
|
"pv_capacity:25000.0\n",
|
|
|
|
"pv_capacity:37500.0\n",
|
|
|
|
"pv_capacity:50000.0\n",
|
2024-05-08 16:07:14 +02:00
|
|
|
"ess_capacity:77777.77777777778\n",
|
2024-05-09 13:15:53 +02:00
|
|
|
"pv_capacity:0.0\n",
|
|
|
|
"pv_capacity:12500.0\n",
|
|
|
|
"pv_capacity:25000.0\n",
|
|
|
|
"pv_capacity:37500.0\n",
|
|
|
|
"pv_capacity:50000.0\n",
|
2024-05-08 16:07:14 +02:00
|
|
|
"ess_capacity:88888.88888888889\n",
|
2024-05-09 13:15:53 +02:00
|
|
|
"pv_capacity:0.0\n",
|
|
|
|
"pv_capacity:12500.0\n",
|
|
|
|
"pv_capacity:25000.0\n",
|
|
|
|
"pv_capacity:37500.0\n",
|
|
|
|
"pv_capacity:50000.0\n",
|
2024-05-08 16:07:14 +02:00
|
|
|
"ess_capacity:100000.0\n",
|
2024-05-09 13:15:53 +02:00
|
|
|
"pv_capacity:0.0\n",
|
|
|
|
"pv_capacity:12500.0\n",
|
|
|
|
"pv_capacity:25000.0\n",
|
|
|
|
"pv_capacity:37500.0\n",
|
|
|
|
"pv_capacity:50000.0\n"
|
2024-05-06 19:23:42 +02:00
|
|
|
]
|
|
|
|
}
|
|
|
|
],
|
|
|
|
"source": [
|
2024-05-08 09:39:56 +02:00
|
|
|
"for ess_capacity in ess_capacities:\n",
|
|
|
|
" print(f\"ess_capacity:{ess_capacity}\")\n",
|
|
|
|
" for pv_capacity in pv_capacities:\n",
|
2024-05-08 16:07:14 +02:00
|
|
|
" print(f\"pv_capacity:{pv_capacity}\")\n",
|
2024-05-04 09:59:27 +02:00
|
|
|
" pv = pv_config(capacity=pv_capacity, \n",
|
|
|
|
" cost_per_kW=pv_cost_per_kW,\n",
|
|
|
|
" lifetime=pv_lifetime, \n",
|
|
|
|
" loss=pv_loss)\n",
|
|
|
|
" ess = ess_config(capacity=ess_capacity, \n",
|
|
|
|
" cost_per_kW=ess_cost_per_kW, \n",
|
|
|
|
" lifetime=ess_lifetime, \n",
|
|
|
|
" loss=ess_loss,\n",
|
|
|
|
" charge_power=ess_capacity,\n",
|
|
|
|
" discharge_power=ess_capacity)\n",
|
|
|
|
" grid = grid_config(capacity=grid_capacity, \n",
|
|
|
|
" grid_loss=grid_loss,\n",
|
|
|
|
" sell_price= sell_price)\n",
|
|
|
|
" energySystem = EnergySystem(pv_type=pv, \n",
|
|
|
|
" ess_type=ess, \n",
|
|
|
|
" grid_type= grid)\n",
|
|
|
|
" benefit = energySystem.simulate(data, time_interval)\n",
|
2024-05-06 19:23:42 +02:00
|
|
|
" results.loc[pv_capacity,ess_capacity] = cal_profit(energySystem, benefit)\n",
|
|
|
|
" affords.loc[pv_capacity,ess_capacity] = energySystem.afford\n",
|
|
|
|
" overload_cnt.loc[pv_capacity,ess_capacity] = energySystem.overload_cnt\n",
|
2024-05-07 10:27:45 +02:00
|
|
|
" costs.loc[pv_capacity,ess_capacity] = energySystem.ess.capacity * energySystem.ess.cost_per_kW + energySystem.pv.capacity * energySystem.pv.cost_per_kW\n",
|
2024-05-06 19:23:42 +02:00
|
|
|
" pv_generated = energySystem.day_generated\n",
|
|
|
|
" ess_generated = energySystem.hour_stored\n",
|
|
|
|
" ess_generated_2 = energySystem.hour_stored_2\n",
|
2024-05-08 09:39:56 +02:00
|
|
|
" plt.figure(figsize=(10,8));\n",
|
|
|
|
" plt.plot(ess_generated)\n",
|
|
|
|
" plt.xlabel('day #')\n",
|
|
|
|
" plt.ylabel('SoC %')\n",
|
|
|
|
" plt.title(f'14:00 ESS SoC \\n PV cap:{pv_capacity}, ESS cap:{ess_capacity}')\n",
|
|
|
|
" plt.savefig(f'plots/ess/1400-{pv_capacity}-{ess_capacity}.png')\n",
|
|
|
|
" plt.close()\n",
|
|
|
|
" plt.figure(figsize=(10,8));\n",
|
|
|
|
" plt.plot(ess_generated_2)\n",
|
|
|
|
" plt.xlabel('day #')\n",
|
|
|
|
" plt.ylabel('SoC%')\n",
|
|
|
|
" plt.title(f'08:00 ESS SoC \\n PV cap:{pv_capacity}, ESS cap:{ess_capacity}')\n",
|
|
|
|
" plt.savefig(f'plots/ess/0800-{pv_capacity}-{ess_capacity}.png')\n",
|
|
|
|
" plt.close()\n",
|
2024-05-07 20:20:09 +02:00
|
|
|
" # print(energySystem.unmet)\n",
|
2024-05-08 09:39:56 +02:00
|
|
|
" # spring_week_start = energySystem.season_start\n",
|
|
|
|
" # spring_week_end = spring_week_start + energySystem.week_length\n",
|
2024-05-07 10:27:45 +02:00
|
|
|
" # summer_week_start = energySystem.season_start + 1 * energySystem.season_step\n",
|
|
|
|
" # summer_week_end = summer_week_start + energySystem.week_length\n",
|
|
|
|
" # autumn_week_start = energySystem.season_start + 2 * energySystem.season_step\n",
|
|
|
|
" # autumn_week_end = autumn_week_start + energySystem.week_length\n",
|
|
|
|
" # winter_week_start = energySystem.season_start + 3 * energySystem.season_step\n",
|
|
|
|
" # winter_week_end = winter_week_start+ energySystem.week_length\n",
|
2024-05-06 19:23:42 +02:00
|
|
|
"\n",
|
2024-05-08 09:39:56 +02:00
|
|
|
" # spring_consume_data = []\n",
|
2024-05-07 10:27:45 +02:00
|
|
|
" # summer_consume_data = []\n",
|
|
|
|
" # autumn_consume_data = []\n",
|
|
|
|
" # winter_consume_data = []\n",
|
2024-05-08 09:39:56 +02:00
|
|
|
" # for index, row in data.iterrows():\n",
|
|
|
|
" # if index in range(spring_week_start, spring_week_end):\n",
|
|
|
|
" # spring_consume_data.append(row['demand'])\n",
|
2024-05-07 10:27:45 +02:00
|
|
|
" # elif index in range(summer_week_start, summer_week_end):\n",
|
|
|
|
" # summer_consume_data.append(row['demand'])\n",
|
|
|
|
" # elif index in range(autumn_week_start, autumn_week_end):\n",
|
|
|
|
" # autumn_consume_data.append(row['demand'])\n",
|
|
|
|
" # elif index in range(winter_week_start, winter_week_end):\n",
|
|
|
|
" # winter_consume_data.append(row['demand'])\n",
|
2024-05-06 19:23:42 +02:00
|
|
|
"\n",
|
2024-05-08 09:39:56 +02:00
|
|
|
" # spring_week_time = list(range(spring_week_start, spring_week_end))\n",
|
2024-05-07 10:27:45 +02:00
|
|
|
" # summer_week_time = list(range(summer_week_start, summer_week_end))\n",
|
|
|
|
" # autumn_week_time = list(range(autumn_week_start, autumn_week_end))\n",
|
|
|
|
" # winter_week_time = list(range(winter_week_start, winter_week_end))\n",
|
2024-05-06 19:23:42 +02:00
|
|
|
"\n",
|
2024-05-08 09:39:56 +02:00
|
|
|
" # spring_pv_generated = energySystem.spring_week_gen\n",
|
2024-05-07 10:27:45 +02:00
|
|
|
" # summer_pv_generated = energySystem.summer_week_gen\n",
|
|
|
|
" # autumn_pv_generated = energySystem.autumn_week_gen\n",
|
|
|
|
" # winter_pv_generated = energySystem.winter_week_gen\n",
|
|
|
|
"\n",
|
|
|
|
" # spring_soc = energySystem.spring_week_soc\n",
|
|
|
|
" # summer_soc = energySystem.summer_week_soc\n",
|
|
|
|
" # autumn_soc = energySystem.autumn_week_soc\n",
|
|
|
|
" # winter_soc = energySystem.winter_week_soc\n",
|
|
|
|
"\n",
|
|
|
|
"\n",
|
|
|
|
" # fig, ax1 = plt.subplots()\n",
|
2024-05-06 19:23:42 +02:00
|
|
|
"\n",
|
2024-05-08 09:39:56 +02:00
|
|
|
" # plt.plot(spring_week_time, spring_pv_generated, label = 'pv generation')\n",
|
|
|
|
" # plt.plot(spring_week_time, spring_consume_data, label = 'factory consume')\n",
|
|
|
|
" # plt.ylabel('Power / kW')\n",
|
|
|
|
" # plt.xlabel('15 min #')\n",
|
|
|
|
" # plt.title(f'ess: {energySystem.ess.capacity/1000 } MWh pv: {energySystem.pv.capacity/1000 } MW spring week generate condition')\n",
|
|
|
|
" # plt.legend()\n",
|
|
|
|
" # plt.savefig(f'plots/{energySystem.ess.capacity}-{energySystem.pv.capacity}-spring.png')\n",
|
|
|
|
" # plt.close()\n",
|
2024-05-06 19:23:42 +02:00
|
|
|
"\n",
|
2024-05-07 10:27:45 +02:00
|
|
|
" # plt.plot(summer_week_time, summer_pv_generated, label = 'pv generation')\n",
|
|
|
|
" # plt.plot(summer_week_time, summer_consume_data, label = 'factory consume')\n",
|
|
|
|
" # plt.ylabel('Power / kW')\n",
|
|
|
|
" # plt.xlabel('15 min #')\n",
|
|
|
|
" # plt.title(f'ess: {energySystem.ess.capacity/1000 } MWh pv: {energySystem.pv.capacity/1000 } MW summer week generate condition')\n",
|
|
|
|
" # plt.legend()\n",
|
|
|
|
" # plt.savefig(f'plots/{energySystem.ess.capacity}-{energySystem.pv.capacity}-summer.png')\n",
|
|
|
|
" # plt.close()\n",
|
2024-05-06 19:23:42 +02:00
|
|
|
"\n",
|
2024-05-07 10:27:45 +02:00
|
|
|
" # plt.plot(autumn_week_time, autumn_pv_generated, label = 'pv generation')\n",
|
|
|
|
" # plt.plot(autumn_week_time, autumn_consume_data, label = 'factory consume')\n",
|
|
|
|
" # plt.ylabel('Power / kW')\n",
|
|
|
|
" # plt.xlabel('15 min #')\n",
|
|
|
|
" # plt.title(f'ess: {energySystem.ess.capacity/1000 } MWh pv: {energySystem.pv.capacity/1000 } MW autumn week generate condition')\n",
|
|
|
|
" # plt.legend()\n",
|
|
|
|
" # plt.savefig(f'plots/{energySystem.ess.capacity}-{energySystem.pv.capacity}-autumn.png')\n",
|
|
|
|
" # plt.close()\n",
|
2024-05-06 19:23:42 +02:00
|
|
|
"\n",
|
2024-05-07 10:27:45 +02:00
|
|
|
" # plt.plot(winter_week_time, winter_pv_generated, label = 'pv generation')\n",
|
|
|
|
" # plt.plot(winter_week_time, winter_consume_data, label = 'factory consume')\n",
|
|
|
|
" # plt.ylabel('Power / kW')\n",
|
|
|
|
" # plt.xlabel('15 min #')\n",
|
|
|
|
" # plt.title(f'ess: {energySystem.ess.capacity/1000 } MWh pv: {energySystem.pv.capacity/1000 } MW winter week generate condition')\n",
|
|
|
|
" # plt.legend()\n",
|
|
|
|
" # plt.savefig(f'plots/{energySystem.ess.capacity}-{energySystem.pv.capacity}-winter.png')\n",
|
|
|
|
" # plt.close()\n",
|
2024-05-06 19:23:42 +02:00
|
|
|
"\n",
|
2024-05-08 09:39:56 +02:00
|
|
|
" # plt.figure();\n",
|
|
|
|
" # plt.plot(pv_generated)\n",
|
|
|
|
" # plt.xlabel('day #')\n",
|
|
|
|
" # plt.ylabel('Electricity kWh')\n",
|
|
|
|
" # plt.title(f'PV generated pv cap:{pv_capacity}, ess cap:{ess_capacity}')\n",
|
|
|
|
" # plt.savefig(f'plots/pv/{pv_capacity}-{ess_capacity}.png')\n",
|
|
|
|
" # plt.close()\n",
|
2024-05-06 19:23:42 +02:00
|
|
|
"\n",
|
|
|
|
"\n",
|
2024-05-04 16:35:55 +02:00
|
|
|
" # plt.show()\n",
|
|
|
|
"\n",
|
2024-05-06 19:23:42 +02:00
|
|
|
"\n",
|
2024-05-04 16:35:55 +02:00
|
|
|
" \n",
|
|
|
|
"\n",
|
|
|
|
"# results = results.astype(float)\n",
|
2024-05-04 09:59:27 +02:00
|
|
|
"\n",
|
|
|
|
"\n",
|
|
|
|
"# pv = pv_config(capacity=100000,cost_per_kW=200,lifetime=25,loss=0.95)\n",
|
|
|
|
"# ess = ess_config(capacity=100000,cost_per_kW=300,lifetime=25,loss=0.95,charge_power=100000,discharge_power=100000)\n",
|
|
|
|
"# grid = grid_config(price_schedule=price_schedule, capacity=5000, grid_loss=0.95, sell_price=0.4)\n",
|
|
|
|
"# grid = grid_config(capacity=50000, grid_loss=0.95, sell_price=0.4)\n",
|
|
|
|
"\n",
|
|
|
|
"\n",
|
|
|
|
" # print(benefit)\n"
|
|
|
|
]
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"cell_type": "code",
|
2024-05-08 16:07:14 +02:00
|
|
|
"execution_count": 7,
|
2024-05-06 19:23:42 +02:00
|
|
|
"metadata": {},
|
2024-05-07 21:06:03 +02:00
|
|
|
"outputs": [],
|
2024-05-06 19:23:42 +02:00
|
|
|
"source": [
|
2024-05-07 21:06:03 +02:00
|
|
|
"def save_data(data, filename):\n",
|
2024-05-08 09:39:56 +02:00
|
|
|
" data.to_csv(filename+'.csv')\n",
|
|
|
|
" data.to_json(filename + '.json')"
|
2024-05-06 19:23:42 +02:00
|
|
|
]
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"cell_type": "code",
|
2024-05-10 00:11:34 +02:00
|
|
|
"execution_count": 34,
|
2024-05-06 19:23:42 +02:00
|
|
|
"metadata": {},
|
2024-05-10 00:11:34 +02:00
|
|
|
"outputs": [],
|
2024-05-04 09:59:27 +02:00
|
|
|
"source": [
|
2024-05-07 20:20:09 +02:00
|
|
|
"import matplotlib.ticker as ticker\n",
|
2024-05-09 13:15:53 +02:00
|
|
|
"from matplotlib.ticker import MaxNLocator, MultipleLocator, FuncFormatter\n",
|
2024-05-10 00:11:34 +02:00
|
|
|
"from matplotlib.colors import LinearSegmentedColormap\n",
|
2024-05-07 21:06:03 +02:00
|
|
|
"\n",
|
|
|
|
"if not os.path.isdir('data'):\n",
|
|
|
|
" os.makedirs('data')\n",
|
|
|
|
"\n",
|
2024-05-08 09:39:56 +02:00
|
|
|
"save_data(results, f'data/{pv_begin}-{pv_end}-{pv_groups}-{ess_begin}-{ess_end}-{ess_groups}-results')\n",
|
|
|
|
"save_data(costs, f'data/{pv_begin}-{pv_end}-{pv_groups}-{ess_begin}-{ess_end}-{ess_groups}-costs')\n",
|
2024-05-10 00:11:34 +02:00
|
|
|
"save_data(overload_cnt, f'data/{pv_begin}-{pv_end}-{pv_groups}-{ess_begin}-{ess_end}-{ess_groups}-overload_cnt')"
|
2024-05-04 09:59:27 +02:00
|
|
|
]
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"cell_type": "code",
|
2024-05-10 01:11:17 +02:00
|
|
|
"execution_count": 35,
|
2024-05-06 19:23:42 +02:00
|
|
|
"metadata": {},
|
|
|
|
"outputs": [
|
2024-05-09 13:15:53 +02:00
|
|
|
{
|
|
|
|
"name": "stdout",
|
|
|
|
"output_type": "stream",
|
|
|
|
"text": [
|
2024-05-10 00:11:34 +02:00
|
|
|
" 0 11 22 33 44 55 66 \\\n",
|
|
|
|
"51 0.674686 0.695805 0.716781 0.735074 0.756564 0.776056 0.790582 \n",
|
|
|
|
"\n",
|
|
|
|
" 77 88 100 101 \n",
|
2024-05-10 01:11:17 +02:00
|
|
|
"51 0.799429 0.804937 0.809189 0.809189 \n"
|
2024-05-09 13:15:53 +02:00
|
|
|
]
|
|
|
|
},
|
2024-05-06 19:23:42 +02:00
|
|
|
{
|
|
|
|
"data": {
|
2024-05-10 00:11:34 +02:00
|
|
|
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAyUAAAMKCAYAAACbbut8AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8fJSN1AAAACXBIWXMAAA9hAAAPYQGoP6dpAADVYklEQVR4nOzdd3wUZf4H8M/MbN/N7iabXiGhgyhHU7qoYEFUFEE4UFHseqJc8YoF9fT8nXpnQ/EUFCuKvYuAgCJNFITQQ3pPNmV7md8fIWvWUBJIMkn283699qXMzs5+ZtP2u893nkeQZVkGERERERGRQkSlAxARERERUWRjUUJERERERIpiUUJERERERIpiUUJERERERIpiUUJERERERIpiUUJERERERIpiUUJERERERIpiUUJERERERIpiUUJERERERIpiUUJEEaG0tBRXXHEFbDYbBEHAf/7zH6UjdRsTJkzAhAkTlI4RZtmyZRAEAYcPH26X499///0QBKFdjt0ddcbvESLqXFiUULdw8OBB3HjjjcjMzIROp4PZbMbo0aPx3//+Fy6XS+l4Xco111wDQRBCN61Wiz59+uDee++F2+0+qWPu3r0b999/f7u9QWyJBQsW4Msvv8Q999yD5cuX4/zzzz/mvk3Pv+ktMTGxzXM999xzWLZsWZsf91QdPnz4mK+DIAh49NFHOyxLZ32NWuK3P08mkwmZmZm44oorsHLlSgSDQaUjEhF1CiqlAxCdqk8//RTTp0+HVqvF3LlzMWjQIHi9XmzYsAF//OMfsWvXLixZskTpmF2KVqvF//73PwBATU0NPvzwQzz44IM4ePAgXn/99VYfb/fu3XjggQcwYcIE9OjRo43Ttszq1atxySWXYOHChS3a/7zzzsPcuXPDtun1+jbP9dxzzyE2NhbXXHNNmx+7LVx11VW48MILm20fMmRIh2U4mddozpw5mDlzJrRabfsFa6GmP08ulwu5ubn4+OOPccUVV2DChAn48MMPYTabFU5JRKQsFiXUpeXk5GDmzJnIyMjA6tWrkZSUFLrv1ltvxYEDB/Dpp58qmPDYnE4nDAaD0jGOSqVS4fe//33o37fccgtGjRqFN998E0888QQSEhIUTHdyysrKYLVaW7x/nz59wl6DrsTtdkOj0UAUT30w/He/+12Xeh0cDgeMRiMkSYIkSUrHAdD85wkAHnroITz66KO45557MH/+fLz99tsKpSMi6hzYvkVd2mOPPYb6+nq89NJLYQVJo169euEPf/hD6N9+vx8PPvggsrKyoNVq0aNHD/z1r3+Fx+MJ7TNlyhRkZmYe9fnOOussDBs2LGzba6+9hqFDh0Kv1yMmJgYzZ85Efn5+2D4TJkzAoEGDsG3bNowbNw4GgwF//etfAQAffvghLrroIiQnJ0Or1SIrKwsPPvggAoFAs+d/9tlnkZmZCb1ejxEjRmD9+vVH7dX2eDy477770KtXL2i1WqSlpeFPf/pT2Hm2hiAIGDNmDGRZxqFDh0Lbc3Nzccstt6Bv377Q6/Ww2WyYPn16WJvWsmXLMH36dADA2WefHWpjWbt2bWifzz//HGPHjoXRaERUVBQuuugi7Nq1q0XZDh06hOnTpyMmJgYGgwFnnnlmWCHaeG2BLMt49tlnQ89/Kv79739j1KhRsNls0Ov1GDp0KN59992j7vvaa69hxIgRMBgMiI6Oxrhx4/DVV18BAHr06IFdu3bh22+/DeVq+rU80bkBwNq1ayEIAt566y38/e9/R0pKCgwGA3766ScIgoAnn3yyWabvv/8egiDgzTffPKXX4Xha8z14sq9R49f222+/xS233IL4+HikpqaG3ffblsHPP/8c48ePR1RUFMxmM4YPH4433ngjdP/69esxffp0pKenh3IvWLCgXdpA//KXv2DSpEl45513sG/fvmY5T/Qzcc0118BkMiEvLw9TpkyByWRCSkoKnn32WQDAzp07MXHiRBiNRmRkZISdJwBUVVVh4cKFOO2002AymWA2m3HBBRfg559/Dtuv8XtsxYoVePjhh5GamgqdTodzzjkHBw4caHZeS5YsQVZWVtjvqaN5+umnMXDgwNDXfdiwYc0yElHk4EgJdWkff/wxMjMzMWrUqBbtf/311+OVV17BFVdcgbvvvhubNm3CI488guzsbLz//vsAgBkzZmDu3LnYsmULhg8fHnpsbm4ufvjhB/zf//1faNvDDz+Mf/zjH7jyyitx/fXXo7y8HE8//TTGjRuH7du3h30yX1lZiQsuuAAzZ87E73//+9Bow7Jly2AymXDXXXfBZDJh9erVuPfee1FbWxv2XIsXL8Ztt92GsWPHYsGCBTh8+DAuvfRSREdHh96IAUAwGMTUqVOxYcMG3HDDDejfvz927tyJJ598Evv27cMHH3xwMi916M1ddHR0aNuWLVvw/fffY+bMmUhNTcXhw4exePFiTJgwAbt374bBYMC4ceNwxx134KmnnsJf//pX9O/fHwBC/12+fDmuvvpqTJ48Gf/617/gdDqxePFijBkzBtu3bz9uu1dpaSlGjRoFp9OJO+64AzabDa+88gqmTp2Kd999F5dddhnGjRuH5cuXY86cOUdtyToWt9uNioqKsG1RUVHQarX473//i6lTp2L27Nnwer146623MH36dHzyySe46KKLQvs/8MADuP/++zFq1CgsWrQIGo0GmzZtwurVqzFp0iT85z//we233w6TyYS//e1vABD6vmjJuTX14IMPQqPRYOHChfB4POjXrx9Gjx6N119/HQsWLAjb9/XXX0dUVBQuueSSE74OTqez2esAAFarFSrV0f+EtOZ78FReo0a33HIL4uLicO+998LhcBzzXJYtW4Z58+Zh4MCBuOeee2C1WrF9+3Z88cUXmDVrFgDgnXfegdPpxM033wybzYbNmzfj6aefRkFBAd55550Tvl6tNWfOHHz11Vf4+uuv0adPHwCt+5kIBAK44IILMG7cODz22GN4/fXXcdttt8FoNOJvf/sbZs+ejWnTpuH555/H3LlzcdZZZ6Fnz54AGoreDz74ANOnT0fPnj1RWlqKF154AePHj8fu3buRnJwclvXRRx+FKIpYuHAhampq8Nhjj2H27NnYtGlTaJ+XXnoJN954I0aNGoU777wThw4dwtSpUxETE4O0tLTQfi+++CLuuOMOXHHFFfjDH/4At9uNHTt2YNOmTaGvBRFFGJmoi6qpqZEByJdcckmL9v/pp59kAPL1118ftn3hwoUyAHn16tWh42q1Wvnuu+8O2++xxx6TBUGQc3NzZVmW5cOHD8uSJMkPP/xw2H47d+6UVSpV2Pbx48fLAOTnn3++WS6n09ls24033igbDAbZ7XbLsizLHo9Httls8vDhw2Wfzxfab9myZTIAefz48aFty5cvl0VRlNevXx92zOeff14GIH/33XfHfI1kWZavvvpq2Wg0yuXl5XJ5ebl84MAB+d///rcsCII8aNAgORgMHjf7xo0bZQDyq6++Gtr2zjvvyADkNWvWhO1bV1cnW61Wef78+WHbS0pKZIvF0mz7b915550ygLBzraurk3v27Cn36NFDDgQCoe0A5FtvvfW4x2u679FuS5cuPep5e71eedCgQfLEiRND2/bv3y+LoihfdtllYTlkWQ57DQcOHBj29Wvtua1Zs0YGIGdmZjbL9cILL8gA5Ozs7LCssbGx8tVXX33c1yAnJ+eYrwMAeePGjaF9x48ff1Lfg6f6Gi1dulQGII8ZM0b2+/1HvS8nJ0eWZVm22+1yVFSUPHLkSNnlch3zuY72Pf3II4+E/ezLsizfd999ckv+hDb+PB3L9u3bZQDyggULZFlu3c/E1VdfLQOQ//nPf4a2VVdXy3q9XhYEQX7rrbdC2/fs2SMDkO+7777QNrfb3ex1z8nJkbVarbxo0aLQtsbvsf79+8sejye0/b///a8MQN65c6csyw3fW/Hx8fIZZ5wRtt+SJUua/Z665JJL5IEDBx7zdSGiyMP2LeqyamtrATR8et0Sn332GQDgrrvuCtt+9913A0CoLaaxhWHFihWQZTm039tvv40zzzw
|
2024-05-06 19:23:42 +02:00
|
|
|
"text/plain": [
|
2024-05-08 16:07:14 +02:00
|
|
|
"<Figure size 1000x900 with 2 Axes>"
|
2024-05-06 19:23:42 +02:00
|
|
|
]
|
|
|
|
},
|
|
|
|
"metadata": {},
|
|
|
|
"output_type": "display_data"
|
|
|
|
}
|
|
|
|
],
|
|
|
|
"source": [
|
2024-05-10 00:11:34 +02:00
|
|
|
"# Coverage Rate\n",
|
2024-05-06 19:23:42 +02:00
|
|
|
"df = overload_cnt\n",
|
2024-05-09 13:15:53 +02:00
|
|
|
"df = (4 * 24 * 365 - df) / (4 * 24 * 365)\n",
|
|
|
|
"df = df.astype(float)\n",
|
2024-05-06 19:23:42 +02:00
|
|
|
"df.index = df.index / 1000\n",
|
2024-05-09 13:15:53 +02:00
|
|
|
"df.index = df.index.map(int)\n",
|
2024-05-06 19:23:42 +02:00
|
|
|
"df.columns = df.columns / 1000\n",
|
2024-05-09 13:15:53 +02:00
|
|
|
"df.columns = df.columns.map(int)\n",
|
2024-05-10 00:11:34 +02:00
|
|
|
"xl = df.columns[-1]\n",
|
|
|
|
"yl = df.index[-1]\n",
|
2024-05-07 10:27:45 +02:00
|
|
|
"min_value = df.min().min()\n",
|
|
|
|
"max_value = df.max().max()\n",
|
|
|
|
"max_scale = max(abs(min_value/1000), abs(max_value/1000))\n",
|
2024-05-10 00:11:34 +02:00
|
|
|
"\n",
|
|
|
|
"\n",
|
|
|
|
"df[df.columns[-1] + 1] = df.iloc[:, -1] \n",
|
|
|
|
"new_Data = pd.DataFrame(index=[df.index[-1] + 1], columns=df.columns)\n",
|
|
|
|
"for i in df.columns:\n",
|
|
|
|
" new_Data[i] = df[i].iloc[-1]\n",
|
|
|
|
"print(new_Data)\n",
|
|
|
|
"df = pd.concat([df, new_Data])\n",
|
|
|
|
"\n",
|
2024-05-06 19:23:42 +02:00
|
|
|
"\n",
|
|
|
|
"plt.figure(figsize=figure_size)\n",
|
2024-05-07 10:27:45 +02:00
|
|
|
"cmap = LinearSegmentedColormap.from_list(\"\", [\"white\", \"blue\"])\n",
|
2024-05-09 13:15:53 +02:00
|
|
|
"ax = sns.heatmap(df, fmt=\".00%\", cmap=cmap, vmin=0, vmax=1, annot=annot_unmet)\n",
|
|
|
|
"\n",
|
2024-05-07 20:20:09 +02:00
|
|
|
"cbar = ax.collections[0].colorbar\n",
|
|
|
|
"cbar.set_ticks([0, 0.25, 0.5, 0.75, 1])\n",
|
|
|
|
"cbar.set_ticklabels(['0%', '25%', '50%', '75%', '100%'])\n",
|
|
|
|
"cbar.ax.yaxis.set_major_formatter(ticker.FuncFormatter(lambda x, pos: f'{x:.0%}'))\n",
|
2024-05-08 16:07:14 +02:00
|
|
|
"X, Y = np.meshgrid(np.arange(df.shape[1]), np.arange(df.shape[0]))\n",
|
|
|
|
"\n",
|
2024-05-10 00:11:34 +02:00
|
|
|
"def fmt(x, pos):\n",
|
|
|
|
" return '{:.0f}%'.format(x * 100)\n",
|
2024-05-09 13:15:53 +02:00
|
|
|
"CS = ax.contour(X, Y, df, colors='black', alpha=0.5)\n",
|
2024-05-08 16:07:14 +02:00
|
|
|
"\n",
|
2024-05-10 00:11:34 +02:00
|
|
|
"ax.clabel(CS, inline=True, fontsize=10, fmt=FuncFormatter(fmt))\n",
|
2024-05-08 16:07:14 +02:00
|
|
|
"\n",
|
2024-05-10 00:11:34 +02:00
|
|
|
"plt.xlim(0, df.shape[1] - 1)\n",
|
|
|
|
"plt.ylim(0, df.shape[0] - 1)\n",
|
2024-05-07 20:20:09 +02:00
|
|
|
"plt.title(title_unmet)\n",
|
2024-05-06 19:23:42 +02:00
|
|
|
"plt.xlabel('ESS Capacity (MWh)')\n",
|
2024-05-07 10:27:45 +02:00
|
|
|
"plt.ylabel('PV Capacity (MW)')\n",
|
2024-05-10 00:11:34 +02:00
|
|
|
"plt.savefig('plots/unmet.png')\n"
|
2024-05-09 13:15:53 +02:00
|
|
|
]
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"cell_type": "code",
|
2024-05-10 01:11:17 +02:00
|
|
|
"execution_count": 36,
|
2024-05-09 13:15:53 +02:00
|
|
|
"metadata": {},
|
|
|
|
"outputs": [
|
|
|
|
{
|
|
|
|
"name": "stdout",
|
|
|
|
"output_type": "stream",
|
|
|
|
"text": [
|
2024-05-10 00:11:34 +02:00
|
|
|
" 0 11 22 33 44 \\\n",
|
|
|
|
"51 6.170524e+06 5.094775e+06 2.957805e+06 644566.934623 -540090.862772 \n",
|
2024-05-09 13:15:53 +02:00
|
|
|
"\n",
|
2024-05-10 00:11:34 +02:00
|
|
|
" 55 66 77 88 100 \\\n",
|
|
|
|
"51 -700903.75164 -966484.874197 -1.209738e+06 -1.450976e+06 -1.785978e+06 \n",
|
2024-05-09 13:15:53 +02:00
|
|
|
"\n",
|
2024-05-10 00:11:34 +02:00
|
|
|
" 101 \n",
|
|
|
|
"51 -1.785978e+06 \n"
|
2024-05-09 13:15:53 +02:00
|
|
|
]
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"data": {
|
2024-05-10 00:11:34 +02:00
|
|
|
"image/png": "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
|
2024-05-09 13:15:53 +02:00
|
|
|
"text/plain": [
|
|
|
|
"<Figure size 1000x900 with 2 Axes>"
|
|
|
|
]
|
|
|
|
},
|
|
|
|
"metadata": {},
|
|
|
|
"output_type": "display_data"
|
|
|
|
}
|
|
|
|
],
|
|
|
|
"source": [
|
2024-05-10 00:11:34 +02:00
|
|
|
"# Profit\n",
|
|
|
|
"df=results\n",
|
2024-05-09 13:15:53 +02:00
|
|
|
"df = df.astype(float)\n",
|
|
|
|
"df.index = df.index / 1000\n",
|
|
|
|
"df.index = df.index.map(int)\n",
|
|
|
|
"df.columns = df.columns / 1000\n",
|
|
|
|
"df.columns = df.columns.map(int)\n",
|
|
|
|
"min_value = df.min().min()\n",
|
|
|
|
"max_value = df.max().max()\n",
|
|
|
|
"max_scale = max(abs(min_value/1000), abs(max_value/1000))\n",
|
2024-05-10 00:11:34 +02:00
|
|
|
"\n",
|
|
|
|
"df[df.columns[-1] + 1] = df.iloc[:, -1] \n",
|
2024-05-09 13:15:53 +02:00
|
|
|
"new_Data = pd.DataFrame(index=[df.index[-1] + 1], columns=df.columns)\n",
|
|
|
|
"for i in df.columns:\n",
|
|
|
|
" new_Data[i] = df[i].iloc[-1]\n",
|
|
|
|
"print(new_Data)\n",
|
|
|
|
"df = pd.concat([df, new_Data])\n",
|
|
|
|
"\n",
|
|
|
|
"X, Y = np.meshgrid(np.arange(df.shape[1]), np.arange(df.shape[0]))\n",
|
|
|
|
"\n",
|
|
|
|
"\n",
|
|
|
|
"plt.figure(figsize=figure_size)\n",
|
2024-05-10 00:11:34 +02:00
|
|
|
"cmap = sns.color_palette(\"coolwarm\", as_cmap=True)\n",
|
|
|
|
"ax = sns.heatmap(df/1000, fmt=\".1f\", cmap=cmap, vmin=-max_scale, vmax=max_scale, annot=annot_benefit)\n",
|
|
|
|
"plt.gca().invert_yaxis()\n",
|
2024-05-09 13:15:53 +02:00
|
|
|
"\n",
|
2024-05-09 13:19:49 +02:00
|
|
|
"def fmt(x, pos):\n",
|
|
|
|
" return '{:.0f}%'.format(x * 100)\n",
|
2024-05-09 13:15:53 +02:00
|
|
|
"\n",
|
2024-05-10 00:11:34 +02:00
|
|
|
"CS = ax.contour(X, Y, df, colors='black', alpha=0.5)\n",
|
|
|
|
"def fmt(x,pos):\n",
|
|
|
|
" return '{:.0f}'.format(x/1000)\n",
|
2024-05-09 13:19:49 +02:00
|
|
|
"ax.clabel(CS, inline=True, fontsize=10, fmt=FuncFormatter(fmt))\n",
|
2024-05-09 13:15:53 +02:00
|
|
|
"\n",
|
2024-05-09 13:19:49 +02:00
|
|
|
"plt.xlim(0, df.shape[1] - 1)\n",
|
|
|
|
"plt.ylim(0, df.shape[0] - 1)\n",
|
2024-05-10 00:11:34 +02:00
|
|
|
"\n",
|
|
|
|
"plt.title(title_benefit)\n",
|
2024-05-09 13:15:53 +02:00
|
|
|
"plt.xlabel('ESS Capacity (MWh)')\n",
|
|
|
|
"plt.ylabel('PV Capacity (MW)')\n",
|
2024-05-10 00:11:34 +02:00
|
|
|
"plt.savefig('plots/benefit.png')"
|
2024-05-09 13:15:53 +02:00
|
|
|
]
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"cell_type": "code",
|
2024-05-10 01:11:17 +02:00
|
|
|
"execution_count": 37,
|
2024-05-09 13:15:53 +02:00
|
|
|
"metadata": {},
|
|
|
|
"outputs": [
|
2024-05-10 00:11:34 +02:00
|
|
|
{
|
|
|
|
"name": "stdout",
|
|
|
|
"output_type": "stream",
|
|
|
|
"text": [
|
|
|
|
" 0 11 22 33 44 55 66 \\\n",
|
|
|
|
"51 10000000 13333333 16666666 20000000 23333333 26666666 30000000 \n",
|
|
|
|
"\n",
|
|
|
|
" 77 88 100 101 \n",
|
|
|
|
"51 33333333 36666666 40000000 40000000 \n"
|
|
|
|
]
|
|
|
|
},
|
2024-05-09 13:15:53 +02:00
|
|
|
{
|
|
|
|
"data": {
|
2024-05-10 00:11:34 +02:00
|
|
|
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAxAAAAMKCAYAAAAVtKIAAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8fJSN1AAAACXBIWXMAAA9hAAAPYQGoP6dpAADuDklEQVR4nOzdeZybZbk//s+zZ09mn+k63aCUQsGCUAtlFUSQKhVERJayCBYXEPT0e/QA+sMqKiouKMqpCyAeNg94BASkRZYii2UthS7TdfYtk317fn88SWZC22mmndxPmnzer1dex2Yyk6s3OencuT/PdUmmaZogIiIiIiIqgmx3AUREREREdODgBoKIiIiIiIrGDQQRERERERWNGwgiIiIiIioaNxBERERERFQ0biCIiIiIiKho3EAQEREREVHRuIEgIiIiIqKicQNBRERERERF4waCiErq5Zdfxkc+8hG43W5IkoS1a9eO+3O0trbikksuGfefK0JbWxskScLvfve7vT72kksuQWtra8lrqgS/+93vIElS/tbT02N3ScL85S9/Kfi7v/LKK3aXREQVhhsIIsE2btyIL3zhC5g+fTocDgd8Ph8WLlyIn/70p4hGo+P+fJFIBDfddBNWrVo17j97b5LJJM4991z09fXhxz/+Mf74xz9i6tSpu33sqlWr8r/w3H333bt9zMKFCyFJEubOnVvKsmkMXnjhBdx0000YGBiwu5Tdyr3uvF5vyZ/rpptuKvjF/YO3jo4OAMOv9QceeGC3P+eaa66BJEkF97W2thb8LLfbjQ9/+MP4wx/+sMv3H3XUUfjjH/+IK6+8cvz/kkREAFS7CyCqJv/3f/+Hc889F4Zh4KKLLsLcuXORSCTw3HPP4YYbbsDbb7+NO++8c1yfMxKJ4OabbwYAnHjiieP6s/dm48aN2LJlC37zm9/g8ssvL+p7HA4H7r33Xlx44YUF97e1teGFF16Aw+HY5XvWr18PWT4wPw+ZOnUqotEoNE2zu5R98sILL+Dmm2/GJZdcgkAgYHc5u/jkJz8p/NTmjjvugMfj2eX+/V2fI444Al/72tcAAO3t7fjtb3+Liy++GPF4HFdccUX+cZMmTcKFF16IVCo17u8nREQANxBEwmzevBnnn38+pk6din/84x9oaWnJf23ZsmXYsGED/u///s/GCsdfV1cXgLH94vTxj38cjzzyCHp6elBfX5+//95770VTUxNmzZqF/v7+gu8xDGNc6o3FYtB1XchmJJVKIZPJQNf13W6K6MD16U9/uuC1O14mTpxYsLG+5JJLMH36dPz4xz8u2EAQEZXagfmRHdEB6NZbb0UoFMJdd91VsHnImTlzJr7yla/k/5xKpfCd73wHM2bMgGEYaG1txf/7f/8P8Xi84PteeeUVnH766aivr4fT6cS0adOwdOlSANan9g0NDQCAm2++OR9/uOmmmwAAHR0duPTSSzFp0iQYhoGWlhYsXrwYbW1te/37/OMf/8Dxxx8Pt9uNQCCAxYsXY926dfmvX3LJJTjhhBMAAOeeey4kSSrqBGTx4sUwDAP3339/wf333nsvzjvvPCiKssv37O4aiIGBAVx77bVobW2FYRiYNGkSLrroonwWPhcjue+++/DNb34TEydOhMvlQjAYBADcf//9mD9/PpxOJ+rr63HhhRdix44duzz3/fffjzlz5sDhcGDu3Ll4+OGHd7lWIXedww9/+EP85Cc/yf83feedd/Z4DcRf/vIXzJ07t+DnFmu014RpmmhtbcXixYt3+b5YLAa/348vfOEL+ft+9rOf4dBDD4XL5UJNTQ2OOuoo3HvvvQCsyM4NN9wAAJg2bVr+9TXy9XP33Xfn17G2thbnn38+tm3bVvC8J554IubOnYs33ngDJ5xwAlwuF2bOnJmP+KxevRrHHHMMnE4nDj74YDz11FNFr8XuiH6+UmloaMDs2bOxceNGu0shoirDEwgiQR599FFMnz4dH/nIR4p6/OWXX47f//73+PSnP42vfe1reOmll7BixQqsW7cu/8tkV1cXTjvtNDQ0NOA//uM/EAgE0NbWhoceegiA9QvGHXfcgauvvhqf+tSncM455wAADj/8cADAkiVL8Pbbb+NLX/oSWltb0dXVhSeffBJbt24dNfbx1FNP4YwzzsD06dNx0003IRqN4mc/+xkWLlyI1157Da2trfjCF76AiRMn4rvf/S6+/OUv4+ijj0ZTU9Ne/94ulwuLFy/Gn/70J1x99dUAgNdffx1vv/02fvvb3+KNN97Y688IhUI4/vjjsW7dOixduhQf+tCH0NPTg0ceeQTbt28v+HT4O9/5DnRdx/XXX494PA5d1/G73/0Ol156KY4++misWLECnZ2d+OlPf4rnn38e//73v/MnKv/3f/+Hz3zmMzjssMOwYsUK9Pf347LLLsPEiRN3W9fKlSsRi8Vw5ZVXwjAM1NbWIpPJ7PK4v//971iyZAnmzJmDFStWoLe3N7/R25u9vSYkScKFF16IW2+9FX19faitrc1/76OPPopgMJj/lPs3v/kNvvzlL+PTn/40vvKVryAWi+GNN97ASy+9hAsuuADnnHMO3nvvPfzpT3/Cj3/84/y65jatt9xyC771rW/hvPPOw+WXX47u7m787Gc/w6JFiwrWEQD6+/tx1lln4fzzz8e5556LO+64A+effz7uuecefPWrX8VVV12FCy64AD/4wQ/w6U9/Gtu2bduv6xpK+Xx9fX273Keq6rhHvFKpFLZv346amppx/blERHtlElHJDQ4OmgDMxYsXF/X4tWvXmgDMyy+/vOD+66+/3gRg/uMf/zBN0zQffvhhE4D58ssv7/FndXd3mwDMG2+8seD+/v5+E4D5gx/8YEx/F9M0zSOOOMJsbGw0e3t78/e9/vrrpizL5kUXXZS/75lnnjEBmPfff/9ef+bIx/71r381JUkyt27dapqmad5www3m9OnTTdM0zRNOOME89NBDC7536tSp5sUXX5z/83/913+ZAMyHHnpol+fJZDIFzzd9+nQzEonkv55IJMzGxkZz7ty5ZjQazd//17/+1QRg/td//Vf+vsMOO8ycNGmSOTQ0lL9v1apVJgBz6tSp+fs2b95sAjB9Pp/Z1dVVUE/uaytXrszfd8QRR5gtLS3mwMBA/r6///3vu/zc3SnmNbF+/XoTgHnHHXcU3H/22Webra2t+TVavHjxLmv9QT/4wQ9MAObmzZsL7m9razMVRTFvueWWgvvffPNNU1XVgvtPOOEEE4B577335u979913TQCmLMvmmjVr8vc/8cQTu6zX7qxcuXK3dZXq+UzTNG+88UYTwG5vBx98cP5xe/v/i2XLlpkf/Od56tSp5mmnnWZ2d3eb3d3d5ptvvml+/vOfNwGYy5YtG3UNRnstEBHtC0aYiATIxWKK/QTzb3/7GwDguuuuK7g/dwFl7lqJ3Ceaf/3rX5FMJsdUk9PphK7rWLVq1S7XFIymvb0da9euxSWXXFLw6fXhhx+Oj370o/na98dpp52G2tpa3HfffTBNE/fddx8++9nPFv39Dz74IObNm4dPfepTu3ztg91tLr74YjidzvyfX3nlFXR1deGLX/xiwbUJZ555JmbPnp1f+507d+LNN9/ERRddVHDB7AknnIDDDjtst3UtWbIk/+n8nuTW9+KLL4bf78/f/9GPfhRz5swZ9XuB4l4TBx10EI455hjcc889+fv6+vrw2GOP4XOf+1x+jQKBALZv346XX355r8/7QQ899BAymQzOO+889PT05G/Nzc2YNWsWnnnmmYLHezwenH/++fk/H3zwwQgEAjjkkENwzDHH5O/P/e9NmzaNuSZRz/fggw/iySefLLitXLlyv+oFrJOphoYGNDQ04LDDDsMf//hHXHrppfjBD36w3z+biGgsuIEgEsDn8wEAhoaGinr8li1bIMsyZs6cWXB/c3MzAoEAtmzZAsD6ZXXJkiW4+eabUV9fj8WLF2PlypW7XCexO4Zh4Pvf/z4ee+wxNDU1YdGiRbj11lvzrSZHqw2wfuH6oEMOOQQ9PT0Ih8NF/T33RNM0nHvuubj33nv
|
2024-05-09 13:15:53 +02:00
|
|
|
"text/plain": [
|
2024-05-10 00:11:34 +02:00
|
|
|
"<Figure size 1000x900 with 2 Axes>"
|
2024-05-09 13:15:53 +02:00
|
|
|
]
|
|
|
|
},
|
|
|
|
"metadata": {},
|
|
|
|
"output_type": "display_data"
|
|
|
|
}
|
|
|
|
],
|
|
|
|
"source": [
|
2024-05-10 00:11:34 +02:00
|
|
|
"# Costs\n",
|
|
|
|
"df = costs\n",
|
|
|
|
"df = df.astype(int)\n",
|
|
|
|
"df.index = df.index / 1000\n",
|
|
|
|
"df.index = df.index.map(int)\n",
|
|
|
|
"df.columns = df.columns / 1000\n",
|
|
|
|
"df.columns = df.columns.map(int)\n",
|
2024-05-09 13:15:53 +02:00
|
|
|
"\n",
|
2024-05-10 00:11:34 +02:00
|
|
|
"df[df.columns[-1] + 1] = df.iloc[:, -1] \n",
|
|
|
|
"new_Data = pd.DataFrame(index=[df.index[-1] + 1], columns=df.columns)\n",
|
|
|
|
"for i in df.columns:\n",
|
|
|
|
" new_Data[i] = df[i].iloc[-1]\n",
|
|
|
|
"print(new_Data)\n",
|
|
|
|
"df = pd.concat([df, new_Data])\n",
|
|
|
|
"X, Y = np.meshgrid(np.arange(df.shape[1]), np.arange(df.shape[0]))\n",
|
2024-05-09 13:15:53 +02:00
|
|
|
"\n",
|
2024-05-10 00:11:34 +02:00
|
|
|
"def fmt(x, pos):\n",
|
|
|
|
" return '{:.0f}'.format(x / 1000000)\n",
|
2024-05-09 13:15:53 +02:00
|
|
|
"\n",
|
2024-05-10 00:11:34 +02:00
|
|
|
"plt.figure(figsize=figure_size)\n",
|
|
|
|
"ax = sns.heatmap(df/1000000, fmt=\".1f\", cmap='viridis', annot=annot_cost)\n",
|
|
|
|
"CS = ax.contour(X, Y, df, colors='black', alpha=0.5)\n",
|
|
|
|
"ax.clabel(CS, inline=True, fontsize=10, fmt=FuncFormatter(fmt))\n",
|
|
|
|
"plt.title(title_cost)\n",
|
|
|
|
"plt.gca().invert_yaxis()\n",
|
|
|
|
"plt.xlim(0, df.shape[1] - 1)\n",
|
|
|
|
"plt.ylim(0, df.shape[0] - 1)\n",
|
|
|
|
"plt.xlabel('ESS Capacity (MWh)')\n",
|
|
|
|
"plt.ylabel('PV Capacity (MW)')\n",
|
|
|
|
"plt.savefig('plots/costs.png')\n"
|
2024-05-09 13:15:53 +02:00
|
|
|
]
|
2024-05-04 09:59:27 +02:00
|
|
|
}
|
|
|
|
],
|
|
|
|
"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",
|
2024-05-10 00:11:34 +02:00
|
|
|
"version": "3.11.9"
|
2024-05-04 09:59:27 +02:00
|
|
|
}
|
|
|
|
},
|
|
|
|
"nbformat": 4,
|
|
|
|
"nbformat_minor": 2
|
|
|
|
}
|