From 1b9080ce74688e49124574957eff312d718d92e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20H=C3=B6ning?= Date: Fri, 12 Mar 2021 12:04:07 +0100 Subject: [PATCH] Determine resolution for plots from data first, then from session (#49) --- flexmeasures/data/queries/utils.py | 2 +- flexmeasures/data/tests/test_queries.py | 16 ++++++++++ flexmeasures/ui/views/analytics.py | 41 +++++++++++++++---------- flexmeasures/ui/views/charts.py | 1 + 4 files changed, 42 insertions(+), 18 deletions(-) diff --git a/flexmeasures/data/queries/utils.py b/flexmeasures/data/queries/utils.py index 5b12d40a5..0fb54a421 100644 --- a/flexmeasures/data/queries/utils.py +++ b/flexmeasures/data/queries/utils.py @@ -209,7 +209,7 @@ def simplify_index( else: raise KeyError(f"Level {col} not found") bdf.index = bdf.index.get_level_values("event_start") - return pd.DataFrame(bdf) + return bdf def multiply_dataframe_with_deterministic_beliefs( diff --git a/flexmeasures/data/tests/test_queries.py b/flexmeasures/data/tests/test_queries.py index 8ac99e8fe..e432cd2d2 100644 --- a/flexmeasures/data/tests/test_queries.py +++ b/flexmeasures/data/tests/test_queries.py @@ -9,6 +9,7 @@ from flexmeasures.data.models.assets import Asset, Power from flexmeasures.data.queries.utils import ( multiply_dataframe_with_deterministic_beliefs, + simplify_index, ) @@ -199,3 +200,18 @@ def test_multiplication_with_both_empty_dataframe(): df = multiply_dataframe_with_deterministic_beliefs(df1, df2) pd.testing.assert_frame_equal(df, df_compare) + + +def test_simplify_index(): + """Check whether simplify_index retains the event resolution.""" + wind_device_1 = Asset.query.filter_by(name="wind-asset-1").one_or_none() + bdf: tb.BeliefsDataFrame = Power.collect( + wind_device_1.name, + ( + datetime(2015, 1, 1, tzinfo=pytz.utc), + datetime(2015, 1, 2, tzinfo=pytz.utc), + ), + resolution=timedelta(minutes=15), + ) + df = simplify_index(bdf) + assert df.event_resolution == timedelta(minutes=15) diff --git a/flexmeasures/ui/views/analytics.py b/flexmeasures/ui/views/analytics.py index 51ab9482b..eb6df9422 100644 --- a/flexmeasures/ui/views/analytics.py +++ b/flexmeasures/ui/views/analytics.py @@ -536,16 +536,6 @@ def make_power_figure( else: title = "Electricity production from %s" % resource_display_name - resolution_str = "?" - if hasattr(data.index, "freq") and data.index.freq is not None: - resolution_str = time_utils.freq_label_to_human_readable_label( - data.index.freqstr - ) - elif "resolution" in session: - resolution_str = time_utils.freq_label_to_human_readable_label( - session["resolution"] - ) - return create_graph( data, unit="MW", @@ -557,7 +547,7 @@ def make_power_figure( schedules=schedule_data, title=title, x_range=shared_x_range, - x_label="Time (resolution of %s)" % resolution_str, + x_label="Time (resolution of %s)" % determine_resolution(data), y_label="Power (in MW)", show_y_floats=True, tools=tools, @@ -581,8 +571,7 @@ def make_prices_figure( forecasts=forecast_data, title=f"Prices for {selected_market.display_name}", x_range=shared_x_range, - x_label="Time (resolution of %s)" - % time_utils.freq_label_to_human_readable_label(session["resolution"]), + x_label="Time (resolution of %s)" % determine_resolution(data), y_label="Price (in %s)" % selected_market.unit, show_y_floats=True, tools=tools, @@ -622,8 +611,7 @@ def make_weather_figure( forecasts=forecast_data, title=title, x_range=shared_x_range, - x_label="Time (resolution of %s)" - % time_utils.freq_label_to_human_readable_label(session["resolution"]), + x_label="Time (resolution of %s)" % determine_resolution(data), y_label=weather_axis_label, legend_location="top_right", show_y_floats=True, @@ -657,8 +645,7 @@ def make_revenues_costs_figure( forecasts=forecast_data, title=f"{rev_cost_str} for {resource_display_name} (on {selected_market.display_name})", x_range=shared_x_range, - x_label="Time (resolution of %s)" - % time_utils.freq_label_to_human_readable_label(session["resolution"]), + x_label="Time (resolution of %s)" % determine_resolution(data), y_label="%s (in %s)" % (rev_cost_str, selected_market.unit[:3]), show_y_floats=True, tools=tools, @@ -676,3 +663,23 @@ def revenue_unit_factor(quantity_unit: str, price_unit: str) -> float: return 1000 else: raise NotImplementedError + + +def determine_resolution(data: pd.DataFrame) -> str: + """ + Determine the resolution to be displayed under the plot. + We try to get it from the DataFrame's meta data, or guess from the actual data. + Lastly, we try the session. + If nothing can be found this way, the resulting string is "?" + """ + if hasattr(data, "event_resolution"): # BeliefsDataFrame + freq_str = time_utils.timedelta_to_pandas_freq_str(data.event_resolution) + elif hasattr(data.index, "freqstr") and data.index.freqstr is not None: + freq_str = data.index.freqstr + elif hasattr(data.index, "inferred_freq") and data.index.inferred_freq is not None: + freq_str = data.index.inferred_freq + elif "resolution" in session: + freq_str = session["resolution"] + else: + return "?" + return time_utils.freq_label_to_human_readable_label(freq_str) diff --git a/flexmeasures/ui/views/charts.py b/flexmeasures/ui/views/charts.py index 23585be5c..307976458 100644 --- a/flexmeasures/ui/views/charts.py +++ b/flexmeasures/ui/views/charts.py @@ -73,6 +73,7 @@ def get_power_chart(chart_request): "resolution": "PT15M", "consumption_as_positive": true "resolution": "PT6H", + "show_individual_traces_for": "none" // can be power or schedules } On your webpage, you need to include the Bokeh libraries, e.g.: