@@ -409,8 +409,12 @@ async def run_workflow(user_config_changes: dict[str, Any]) -> SolarAnalysisData
409409 rolling_view_average = RollingPreparer (rolling_view_average_config ).prepare (
410410 data [[long_term_view_col_to_plot ]]
411411 )
412- rolling_view_real_time = RollingPreparer (rolling_view_real_time_config ).prepare (
413- data_higher_fs [real_time_view_col_to_plot ] / normalisation_factor
412+ rolling_view_real_time = (
413+ pd .DataFrame ()
414+ if data_higher_fs .empty
415+ else RollingPreparer (rolling_view_real_time_config ).prepare (
416+ data_higher_fs [real_time_view_col_to_plot ] / normalisation_factor
417+ )
414418 )
415419 daily_production_view = DailyPreparer (daily_plot_config ).prepare (data )
416420 statistical_view = ProfilePreparer (statistical_plot_config ).prepare (data )
@@ -493,54 +497,67 @@ async def run_workflow(user_config_changes: dict[str, Any]) -> SolarAnalysisData
493497 fig = figures_and_axes ["fig_real_time" ]["figure" ],
494498 ax = figures_and_axes ["fig_real_time" ]["axes" ][0 ],
495499 )
496- if plot_settings ["show_annotation" ]:
497- if len (real_time_view_col_to_plot ) == 1 :
498- for col in real_time_view_col_to_plot :
499- recent_y = rolling_view_real_time [str (col )].iloc [- 2 ]
500- _annotate_last_point (
501- figures_and_axes ["fig_real_time" ]["axes" ][0 ], recent_y
502- )
503- patch = Patch (
504- color = plot_settings ["patch_colour" ], label = patch_label
505- )
506- figures_and_axes ["fig_real_time" ]["axes" ][0 ].set_ylabel (real_time_view_ylabel )
507-
508- if plot_settings ["legend_update_on" ] == "figure" :
509- _legend_kwargs_copy = plot_settings ["legend_kwargs" ].copy ()
510- # divide legend labels into groups of 2 if needed
511- _legend_kwargs_copy ["ncol" ] = max (
512- _legend_kwargs_copy ["ncol" ],
513- (
514- len (
515- figures_and_axes ["fig_real_time" ]["axes" ][
516- 0
517- ].get_legend_handles_labels ()[1 ]
518- )
519- + 1
520- )
521- // 2 ,
522- )
500+ if data_higher_fs .empty :
501+ reason = NoDataAvailableError ("No data available for real-time view." )
502+ print (f"{ reason } Skipping this plot." )
503+ print (f"{ type (reason ).__name__ } : { reason } . Skipping this plot." )
504+ # the plotter automatically hides the axis when data is empty
505+ # but we need to deal with the figure itself
506+ # we can safely clear the figure like this because it only plots rolling_view_real_time
507+ figures_and_axes ["fig_real_time" ]["figure" ].clf ()
523508 else :
524- _legend_kwargs_copy = plot_settings ["legend_kwargs" ]
525- plot_manager .update_legend (
526- fig_id = "fig_real_time" ,
527- axs = [figures_and_axes ["fig_real_time" ]["axes" ][0 ]],
528- on = plot_settings ["legend_update_on" ],
529- modifications = {
530- "additional_items" : (
531- [(patch , patch_label )] if plot_settings ["show_annotation" ] else None
532- ),
533- "replace_label" : {
534- str (col ): (
535- tm .translate ("component_{value}" , value = col )
536- if config .split_real_time_view_per_inverter
537- else production_legend_label
509+ if plot_settings ["show_annotation" ]:
510+ if len (real_time_view_col_to_plot ) == 1 :
511+ for col in real_time_view_col_to_plot :
512+ recent_y = rolling_view_real_time [str (col )].iloc [- 2 ]
513+ _annotate_last_point (
514+ figures_and_axes ["fig_real_time" ]["axes" ][0 ], recent_y
515+ )
516+ patch = Patch (
517+ color = plot_settings ["patch_colour" ], label = patch_label
518+ )
519+ figures_and_axes ["fig_real_time" ]["axes" ][0 ].set_ylabel (
520+ real_time_view_ylabel
521+ )
522+
523+ if plot_settings ["legend_update_on" ] == "figure" :
524+ _legend_kwargs_copy = plot_settings ["legend_kwargs" ].copy ()
525+ # divide legend labels into groups of 2 if needed
526+ _legend_kwargs_copy ["ncol" ] = max (
527+ _legend_kwargs_copy ["ncol" ],
528+ (
529+ len (
530+ figures_and_axes ["fig_real_time" ]["axes" ][
531+ 0
532+ ].get_legend_handles_labels ()[1 ]
533+ )
534+ + 1
538535 )
539- for col in real_time_view_col_to_plot
536+ // 2 ,
537+ )
538+ else :
539+ _legend_kwargs_copy = plot_settings ["legend_kwargs" ]
540+ plot_manager .update_legend (
541+ fig_id = "fig_real_time" ,
542+ axs = [figures_and_axes ["fig_real_time" ]["axes" ][0 ]],
543+ on = plot_settings ["legend_update_on" ],
544+ modifications = {
545+ "additional_items" : (
546+ [(patch , patch_label )]
547+ if plot_settings ["show_annotation" ]
548+ else None
549+ ),
550+ "replace_label" : {
551+ str (col ): (
552+ tm .translate ("component_{value}" , value = col )
553+ if config .split_real_time_view_per_inverter
554+ else production_legend_label
555+ )
556+ for col in real_time_view_col_to_plot
557+ },
540558 },
541- },
542- ** _legend_kwargs_copy ,
543- )
559+ ** _legend_kwargs_copy ,
560+ )
544561 # ------------------- #
545562
546563 # --- plot the statistical production profile --- #
@@ -810,7 +827,9 @@ async def run_workflow(user_config_changes: dict[str, Any]) -> SolarAnalysisData
810827 for fig in figures_and_axes .keys ():
811828 plot_manager .adjust_axes_spacing (fig_id = fig , pixels = 100.0 )
812829
813- output .real_time_view [mid ] = rolling_view_real_time
830+ output .real_time_view [mid ] = (
831+ pd .DataFrame () if data_higher_fs .empty else rolling_view_real_time
832+ )
814833 output .rolling_view_short_term [mid ] = rolling_view_short_term
815834 output .rolling_view_long_term [mid ] = rolling_view_long_term
816835 output .rolling_view_average [mid ] = rolling_view_average
0 commit comments