From 6cc9a5fd44ecc8e2188d633b8184557f26379ddf Mon Sep 17 00:00:00 2001 From: celle1234 <64745412+celle1234@users.noreply.github.com> Date: Sat, 8 Feb 2025 00:47:21 +0100 Subject: [PATCH] visualize: fix timestamps on diagrams (#430) Closes #387 * visualize: fix timestamps on diagrams * set start time in all graphs to the same beginning hour --------- Co-authored-by: Normann --- src/akkudoktoreos/utils/visualize.py | 65 ++++++++++++++++++++-------- 1 file changed, 46 insertions(+), 19 deletions(-) diff --git a/src/akkudoktoreos/utils/visualize.py b/src/akkudoktoreos/utils/visualize.py index 3c63ab3..fc684c9 100644 --- a/src/akkudoktoreos/utils/visualize.py +++ b/src/akkudoktoreos/utils/visualize.py @@ -13,6 +13,7 @@ import pendulum from matplotlib.backends.backend_pdf import PdfPages from akkudoktoreos.core.coreabc import ConfigMixin +from akkudoktoreos.core.ems import EnergieManagementSystem from akkudoktoreos.core.logging import get_logger from akkudoktoreos.optimization.genetic import OptimizationParameters from akkudoktoreos.utils.datetimeutil import to_datetime @@ -147,14 +148,16 @@ class VisualizationReport(ConfigMixin): # Format the time axis plt.gca().xaxis.set_major_formatter( - mdates.DateFormatter("%Y-%m-%d") + mdates.DateFormatter("%Y-%m-%d", tz=self.config.timezone) ) # Show date and time plt.gca().xaxis.set_major_locator( - mdates.DayLocator(interval=1, tz=None) + mdates.DayLocator(interval=1, tz=self.config.timezone) ) # Major ticks every day - plt.gca().xaxis.set_minor_locator(mdates.HourLocator(interval=3, tz=None)) + plt.gca().xaxis.set_minor_locator( + mdates.HourLocator(interval=2, tz=self.config.timezone) + ) # Minor ticks every 6 hours - plt.gca().xaxis.set_minor_formatter(mdates.DateFormatter("%H")) + plt.gca().xaxis.set_minor_formatter(mdates.DateFormatter("%H", tz=self.config.timezone)) # plt.gcf().autofmt_xdate(rotation=45, which="major") # Auto-format the x-axis for readability @@ -174,6 +177,7 @@ class VisualizationReport(ConfigMixin): # Add vertical line for the current date if within the axis range current_time = pendulum.now(self.config.timezone) + # current_time = pendulum.now().add(hours=1) if timestamps[0].subtract(hours=2) <= current_time <= timestamps[-1]: plt.axvline(current_time, color="r", linestyle="--", label="Now") plt.text(current_time, plt.ylim()[1], "Now", color="r", ha="center", va="bottom") @@ -187,8 +191,10 @@ class VisualizationReport(ConfigMixin): hours_since_start = [(t - timestamps[0]).total_seconds() / 3600 for t in timestamps] # ax2.set_xticks(timestamps[::48]) # Set ticks every 12 hours # ax2.set_xticklabels([f"{int(h)}" for h in hours_since_start[::48]]) - ax2.set_xticks(timestamps[:: len(timestamps) // 24]) # Select 10 evenly spaced ticks - ax2.set_xticklabels([f"{int(h)}" for h in hours_since_start[:: len(timestamps) // 24]]) + # ax2.set_xticks(timestamps[:: len(timestamps) // 24]) # Select 10 evenly spaced ticks + ax2.set_xticks(timestamps[:: len(timestamps) // 12]) # Select 10 evenly spaced ticks + # ax2.set_xticklabels([f"{int(h)}" for h in hours_since_start[:: len(timestamps) // 24]]) + ax2.set_xticklabels([f"{int(h)}" for h in hours_since_start[:: len(timestamps) // 12]]) if x2label: ax2.set_xlabel(x2label) @@ -416,15 +422,17 @@ def prepare_visualize( parameters: OptimizationParameters, results: dict, filename: str = "visualization_results.pdf", - start_hour: Optional[int] = 0, + start_hour: int = 0, ) -> None: report = VisualizationReport(filename) - next_full_hour_date = pendulum.now(report.config.timezone).start_of("hour").add(hours=1) + # next_full_hour_date = pendulum.now(report.config.timezone).start_of("day").add(hours=start_hour) + # next_full_hour_date = to_datetime().set(minute=0, second=0, microsecond=0) + next_full_hour_date = EnergieManagementSystem.set_start_datetime() # Group 1: report.create_line_chart_date( - next_full_hour_date, # start_date + next_full_hour_date, [ - parameters.ems.gesamtlast, + parameters.ems.gesamtlast[start_hour:], ], title="Load Profile", # xlabel="Hours", # not enough space @@ -432,9 +440,9 @@ def prepare_visualize( labels=["Total Load (Wh)"], ) report.create_line_chart_date( - next_full_hour_date, # start_date + next_full_hour_date, [ - parameters.ems.pv_prognose_wh, + parameters.ems.pv_prognose_wh[start_hour:], ], title="PV Forecast", # xlabel="Hours", # not enough space @@ -442,8 +450,13 @@ def prepare_visualize( ) report.create_line_chart_date( - next_full_hour_date, # start_date - [np.full(len(parameters.ems.gesamtlast), parameters.ems.einspeiseverguetung_euro_pro_wh)], + next_full_hour_date, + [ + np.full( + len(parameters.ems.gesamtlast) - start_hour, + parameters.ems.einspeiseverguetung_euro_pro_wh, + ) + ], title="Remuneration", # xlabel="Hours", # not enough space ylabel="€/Wh", @@ -451,9 +464,9 @@ def prepare_visualize( ) if parameters.temperature_forecast: report.create_line_chart_date( - next_full_hour_date, # start_date + next_full_hour_date, [ - parameters.temperature_forecast, + parameters.temperature_forecast[start_hour:], ], title="Temperature Forecast", # xlabel="Hours", # not enough space @@ -502,21 +515,35 @@ def prepare_visualize( ) report.create_line_chart_date( next_full_hour_date, # start_date - [parameters.ems.strompreis_euro_pro_wh], + [parameters.ems.strompreis_euro_pro_wh[start_hour:]], # title="Electricity Price", # not enough space # xlabel="Date", # not enough space ylabel="Electricity Price (€/Wh)", x2label=None, # not enough space ) + labels = list( + item + for sublist in zip( + list(str(i) for i in range(0, 23, 2)), list(str(" ") for i in range(0, 23, 2)) + ) + for item in sublist + ) + labels = labels[start_hour:] + labels + report.create_bar_chart( - list(str(i) for i in range(len(results["ac_charge"]))), - [results["ac_charge"], results["dc_charge"], results["discharge_allowed"]], + labels, + [ + results["ac_charge"][start_hour:], + results["dc_charge"][start_hour:], + results["discharge_allowed"][start_hour:], + ], title="AC/DC Charging and Discharge Overview", ylabel="Relative Power (0-1) / Discharge (0 or 1)", label_names=["AC Charging (relative)", "DC Charging (relative)", "Discharge Allowed"], colors=["blue", "green", "red"], bottom=3, + xlabels=labels, ) report.finalize_group()