From 50727aaa5bddb4d33a0b51fa388dfe73f15d5cfd Mon Sep 17 00:00:00 2001 From: Eric Duminil <eric.duminil@gmail.com> Date: Tue, 13 Jun 2023 11:27:45 +0200 Subject: [PATCH] Repaired comparison SimStadt vs Urbi --- .../simstadt_urbi/compare_heat_demands.py | 33 ++++++++++-------- ..._urbi_heat_demands_Gromb\303\274hl_v2.png" | Bin 44524 -> 44524 bytes 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/python_scripts/simstadt_urbi/compare_heat_demands.py b/python_scripts/simstadt_urbi/compare_heat_demands.py index 5e7a0dd..9100833 100644 --- a/python_scripts/simstadt_urbi/compare_heat_demands.py +++ b/python_scripts/simstadt_urbi/compare_heat_demands.py @@ -5,15 +5,15 @@ import matplotlib.pyplot as plt PROJ_DIR = Path(__file__).parent CITYGML = 'Grombühl_v2' URBI_HEAT_DEMAND = 'totalPrimaryEnergyDemandHeating [kWh/a]' -S_DEMAND = 'Simstadt heat demand [MWh / a]' # Inkl Warmwasser? +S_DEMAND = 'Simstadt heat demand [MWh / a]' # Inkl Warmwasser? U_DEMAND = 'Urbi+ heat demand [MWh / a]' AREA = 'Area [m²]' TYPE = 'Usage Type' -SUFFIX = '_Bensfeld' +SUFFIX = '' # Could be 'Bensheim', for example # Feldberg : 2.493 (Average : 3.0°C, Min : -18°C) # Original : 2.487 (Average : 7.9°C, Min : -12°C), Würzburg -# Bensfeld : 2.475 (Average : 10.2°C, Min : -10°C) +# Bensheim : 2.475 (Average : 10.2°C, Min : -10°C) def get_simstadt_heat_demand(): @@ -26,17 +26,19 @@ def get_simstadt_heat_demand(): decimal='.') simstadt_df = simstadt_df.rename({ - 'Total Yearly Heat+DHW demand': S_DEMAND, - 'PrimaryUsageZoneArea': AREA, - 'PrimaryUsageZoneType': TYPE, - }, axis='columns') + 'Total Yearly Heat+DHW demand': S_DEMAND, + 'PrimaryUsageZoneArea': AREA, + 'PrimaryUsageZoneType': TYPE, + }, axis='columns') simstadt_df[S_DEMAND] = simstadt_df[S_DEMAND] / 1000 # kWh -> MWh simstadt_df = simstadt_df.set_index('GMLId') - by_type_df = simstadt_df.groupby([TYPE]).sum(numeric_only=True)[[AREA, S_DEMAND]] + by_type_df = simstadt_df.groupby([TYPE]).sum( + numeric_only=True)[[AREA, S_DEMAND]] - by_type_df['Specific heat demand [kWh / (m².a)]'] = by_type_df[S_DEMAND] / by_type_df[AREA] * 1000 + by_type_df['Specific heat demand [kWh / (m².a)]'] = by_type_df[S_DEMAND] / \ + by_type_df[AREA] * 1000 print(by_type_df.round(1).to_string()) @@ -67,14 +69,17 @@ def compare_results(simstadt_df, urbi_df): simstadt_urbi = simstadt_df.join(urbi_df)[[S_DEMAND, U_DEMAND]] simstadt_urbi = simstadt_urbi.dropna() - simstadt_urbi.round(1).to_csv(f'simstadt_vs_urbi_heat_demands_{CITYGML}{SUFFIX}.csv', sep=';', decimal='.') + simstadt_urbi.round(1).to_csv( + f'simstadt_vs_urbi_heat_demands_{CITYGML}{SUFFIX}.csv', sep=';', decimal='.') plt.rcParams["figure.figsize"] = (10, 10) - ax = simstadt_urbi.plot.scatter(x=S_DEMAND, y=U_DEMAND, title=f'Urbi vs SimStadt Heat-demand\n{CITYGML}{SUFFIX}') + fig = simstadt_urbi.plot.scatter( + x=S_DEMAND, y=U_DEMAND, title=f'Urbi vs SimStadt Heat-demand\n{CITYGML}{SUFFIX}') max_heat_demand = simstadt_urbi.max().max() - ax.plot([0, max_heat_demand], [0, max_heat_demand]) - ax.axis('equal') - plt.savefig(f'simstadt_vs_urbi_heat_demands_{CITYGML}{SUFFIX}.png', bbox_inches='tight') + fig.plot([0, max_heat_demand], [0, max_heat_demand]) + fig.axis('equal') + plt.savefig( + f'simstadt_vs_urbi_heat_demands_{CITYGML}{SUFFIX}.png', bbox_inches='tight') print("Correlation:") print(simstadt_urbi.corr()) diff --git "a/python_scripts/simstadt_urbi/simstadt_vs_urbi_heat_demands_Gromb\303\274hl_v2.png" "b/python_scripts/simstadt_urbi/simstadt_vs_urbi_heat_demands_Gromb\303\274hl_v2.png" index a213c1d33a3a87825677c524bb8ef5f1de0598ad..39720b8569c42c998c42466e3f6a589ee8a1c7ad 100644 GIT binary patch delta 4692 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 OjSX)Y6kopk^#1_XpY~1w delta 4689 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 AE&u=k -- GitLab