mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-06-08 11:17:27 +00:00
Creating utility functions to produce slides
This commit is contained in:
parent
9f205e3dce
commit
80a542f02e
6 changed files with 118 additions and 18 deletions
|
|
@ -343,7 +343,7 @@ class Property:
|
|||
else:
|
||||
output["glazed_type_ending"] = "double glazing installed during or after 2002"
|
||||
|
||||
if recommendation["type"] == "heating":
|
||||
if recommendation["type"] in ["heating", "hot_water_tank_insulation"]:
|
||||
# We update the data, as defined in the recommendaton
|
||||
|
||||
simulation_config = recommendation["simulation_config"]
|
||||
|
|
@ -363,9 +363,9 @@ class Property:
|
|||
"internal_wall_insulation", "external_wall_insulation", "cavity_wall_insulation",
|
||||
"loft_insulation", "room_roof_insulation", "flat_roof_insulation",
|
||||
"solid_floor_insulation", "suspended_floor_insulation", "exposed_floor_insulation",
|
||||
"windows_glazing", "solar_pv", "heating",
|
||||
"windows_glazing", "solar_pv", "heating", "hot_water_tank_insulation"
|
||||
]:
|
||||
raise NotImplementedError("Implement me")
|
||||
raise NotImplementedError("Implement me, given type %s" % recommendation["type"])
|
||||
|
||||
output['id'] = "+".join([str(property_id), str(primary_recommendation_id)])
|
||||
|
||||
|
|
|
|||
|
|
@ -78,6 +78,8 @@ async def trigger_plan(body: PlanTriggerRequest):
|
|||
# TODO: We should store the trigger file path in the database with the plan so we can track the file that
|
||||
# triggered the plan
|
||||
|
||||
# TODO: Create the ability to congigure/switch off certain measures
|
||||
|
||||
try:
|
||||
session.begin()
|
||||
logger.info("Getting the inputs")
|
||||
|
|
|
|||
65
etl/customers/slide_utils.py
Normal file
65
etl/customers/slide_utils.py
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
import matplotlib.pyplot as plt
|
||||
from sqlalchemy.orm import Session
|
||||
from backend.app.db.utils import row2dict
|
||||
from backend.app.db.models.portfolio import PropertyModel
|
||||
|
||||
EPC_COLOURS = {
|
||||
"A": "#008054",
|
||||
"B": "#1ab559",
|
||||
"C": "#8ccf45",
|
||||
"D": "#ffd600",
|
||||
"E": "#fcab66",
|
||||
"F": "#f08024",
|
||||
"G": "#e8143b"
|
||||
}
|
||||
|
||||
|
||||
def get_properties_by_portfolio_id(session: Session, portfolio_id: int):
|
||||
"""
|
||||
This function retrieves all properties associated with a given portfolio_id.
|
||||
|
||||
:param session: The SQLAlchemy session used to execute the query.
|
||||
:param portfolio_id: The ID of the portfolio for which to retrieve properties.
|
||||
:return: A list of dictionaries, where each dictionary represents a property.
|
||||
Returns an empty list if no properties are found.
|
||||
"""
|
||||
properties = session.query(PropertyModel).filter(PropertyModel.portfolio_id == portfolio_id).all()
|
||||
|
||||
# Convert the SQLAlchemy objects to dictionaries
|
||||
properties_dict = [row2dict(p) for p in properties] if properties else []
|
||||
|
||||
return properties_dict
|
||||
|
||||
|
||||
def plot_epc_distribution(df, title='Your units', figsize=(10, 6)):
|
||||
"""
|
||||
Plots a horizontal bar chart of EPC rating distribution with percentages annotated on the bars.
|
||||
|
||||
:param df: DataFrame with columns ['current_epc_rating', 'count', 'percentage']
|
||||
:param title: Title of the plot (default is 'EPC Rating Distribution by Percentage')
|
||||
:param figsize: Figure size as a tuple (default is (10, 6))
|
||||
"""
|
||||
# Sort the DataFrame for a consistent plotting order
|
||||
df_sorted = df.sort_values('percentage', ascending=True)
|
||||
|
||||
colors = df_sorted['current_epc_rating'].map(EPC_COLOURS) # Map the EPC ratings to colors
|
||||
|
||||
# Create the horizontal bar chart
|
||||
plt.figure(figsize=figsize)
|
||||
bars = plt.barh(df_sorted['current_epc_rating'], df_sorted['percentage'], color=colors)
|
||||
|
||||
# Annotate the bars with percentage values
|
||||
for bar in bars:
|
||||
width = bar.get_width()
|
||||
label_x_pos = width + 1 # Adjust the offset for the label if necessary
|
||||
plt.text(label_x_pos, bar.get_y() + bar.get_height() / 2, f'{width}%', va='center')
|
||||
|
||||
# Customize the plot aesthetics for better readability and presentation
|
||||
plt.xlabel('Percentage')
|
||||
plt.ylabel('EPC Rating')
|
||||
plt.title(title)
|
||||
plt.tight_layout() # Adjust layout to not cut off labels
|
||||
plt.grid(axis='x', linestyle='--') # Add a light grid for better readability
|
||||
|
||||
# Show the plot
|
||||
plt.show()
|
||||
26
etl/customers/urban_splash/slides.py
Normal file
26
etl/customers/urban_splash/slides.py
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
"""
|
||||
This script contains the code to generate the data required to populate the slides
|
||||
We connect to the database amd extract the data for the portfolio needed so it is recommended to use
|
||||
a environment akin to the backend to run this script
|
||||
"""
|
||||
import pandas as pd
|
||||
from backend.app.db.connection import db_engine
|
||||
from sqlalchemy.orm import sessionmaker
|
||||
from etl.customers.slide_utils import get_properties_by_portfolio_id, plot_epc_distribution
|
||||
|
||||
PORTFOLIO_ID = 66
|
||||
|
||||
|
||||
def app():
|
||||
# Connect to database
|
||||
session = sessionmaker(bind=db_engine)()
|
||||
|
||||
# Get the properties for the portfolio
|
||||
properties = get_properties_by_portfolio_id(session, PORTFOLIO_ID)
|
||||
|
||||
# The first visual we want to produce is a horizontal bar chart showing the number of properties at each current
|
||||
# EPC band
|
||||
|
||||
properties_df = pd.DataFrame(properties)
|
||||
epc_rating_summary = properties_df.groupby("current_epc_rating").size().reset_index(name="count")
|
||||
epc_rating_summary["percentage"] = epc_rating_summary["count"] / epc_rating_summary["count"].sum() * 100
|
||||
|
|
@ -58,21 +58,22 @@ class Recommendations:
|
|||
property_recommendations = []
|
||||
phase = 0
|
||||
|
||||
# Building Fabric
|
||||
self.wall_recomender.recommend(phase=phase)
|
||||
if self.wall_recomender.recommendations:
|
||||
property_recommendations.append(self.wall_recomender.recommendations)
|
||||
phase += 1
|
||||
|
||||
# Ventilation recommendations
|
||||
# We only produce a ventilation recommendation if the property is recommended to have wall or roof insulation
|
||||
# We will not attribute a SAP impact to the ventilation recommendation, since we've seen that this has no
|
||||
# real impact on the SAP score. Therefore, we don't need to include phasing for ventilation. If we have any
|
||||
# wall or roof recommendations, we will ensure that ventilation is included in the simulation
|
||||
if self.wall_recomender.recommendations or self.roof_recommender.recommendations:
|
||||
self.ventilation_recomender.recommend()
|
||||
if self.ventilation_recomender.recommendation:
|
||||
property_recommendations.append(self.ventilation_recomender.recommendation)
|
||||
print("WALL RECOMMENDATIONS HAVE BEEN COMMENTED OUT TEMPORARILY - ADD ME BACK IN")
|
||||
# # Building Fabric
|
||||
# self.wall_recomender.recommend(phase=phase)
|
||||
# if self.wall_recomender.recommendations:
|
||||
# property_recommendations.append(self.wall_recomender.recommendations)
|
||||
# phase += 1
|
||||
#
|
||||
# # Ventilation recommendations
|
||||
# # We only produce a ventilation recommendation if the property is recommended to have wall or roof insulation
|
||||
# # We will not attribute a SAP impact to the ventilation recommendation, since we've seen that this has no
|
||||
# # real impact on the SAP score. Therefore, we don't need to include phasing for ventilation. If we have any
|
||||
# # wall or roof recommendations, we will ensure that ventilation is included in the simulation
|
||||
# if self.wall_recomender.recommendations or self.roof_recommender.recommendations:
|
||||
# self.ventilation_recomender.recommend()
|
||||
# if self.ventilation_recomender.recommendation:
|
||||
# property_recommendations.append(self.ventilation_recomender.recommendation)
|
||||
|
||||
self.roof_recommender.recommend(phase=phase)
|
||||
if self.roof_recommender.recommendations:
|
||||
|
|
@ -100,6 +101,12 @@ class Recommendations:
|
|||
property_recommendations.append(self.heating_recommender.recommendations)
|
||||
phase += 1
|
||||
|
||||
# Hot water
|
||||
self.hotwater_recommender.recommend(phase=phase)
|
||||
if self.hotwater_recommender.recommendations:
|
||||
property_recommendations.append(self.hotwater_recommender.recommendations)
|
||||
phase += 1
|
||||
|
||||
self.lighting_recommender.recommend(phase=phase)
|
||||
if self.lighting_recommender.recommendation:
|
||||
property_recommendations.append(self.lighting_recommender.recommendation)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue