Coverage for functions \ flipdare \ analysis \ plot \ time_series_plot.py: 100%

44 statements  

« prev     ^ index     » next       coverage.py v7.13.0, created at 2026-05-08 12:22 +1000

1#!/usr/bin/env python 

2# Copyright (c) 2026 Flipdare Pty Ltd. All rights reserved. 

3# 

4# This file is part of Flipdare's proprietary software and contains 

5# confidential and copyrighted material. Unauthorised copying, 

6# modification, distribution, or use of this file is strictly 

7# prohibited without prior written permission from Flipdare Pty Ltd. 

8# 

9# This software includes third-party components licensed under MIT, 

10# BSD, and Apache 2.0 licences. See THIRD_PARTY_NOTICES for details. 

11# 

12 

13import io 

14from flipdare.analysis.data._time_series_protocol import TimeSeriesPlotInfo 

15from flipdare.analysis.data_analysis import AnalysisResult, DataAnalysis, DataAnalysisProps 

16from flipdare.analysis.plotter import Plotter, ScatterData 

17from flipdare.app_log import LOG 

18from flipdare.constants import IS_TRACE 

19 

20__all__ = ["TimeSeriesPlot"] 

21 

22 

23class TimeSeriesPlot: 

24 def __init__( 

25 self, 

26 title: str, 

27 info: TimeSeriesPlotInfo, 

28 analysis_props: DataAnalysisProps | None = None, 

29 ) -> None: 

30 self.title = title 

31 self.info = info 

32 self.analysis_props = analysis_props 

33 self._outliers: list[AnalysisResult] | None = None 

34 

35 @property 

36 def outliers(self) -> list[AnalysisResult]: 

37 """Get outlier results for each set of values.""" 

38 if self._outliers is not None: 

39 return self._outliers 

40 

41 results: list[AnalysisResult] = [] 

42 data = self.info.data 

43 for values in data: 

44 analysis = DataAnalysis(values=values, props=self.analysis_props) 

45 result = analysis.analyze() 

46 results.append(result) 

47 self._outliers = results 

48 return results 

49 

50 def create_notes(self) -> list[str]: 

51 notes: list[str] = [] 

52 outliers = self.outliers 

53 for outlier in outliers: 

54 n = outlier.notes 

55 notes.extend(n) 

56 

57 return notes 

58 

59 def create(self) -> io.BytesIO: 

60 title = self.title 

61 x_label = self.info.x_title 

62 y_label = self.info.y_title 

63 

64 outlier_result = self.outliers 

65 scatter_data: list[ScatterData] = [] 

66 scatter_data = [ 

67 result.outlier_scatter_data 

68 for result in outlier_result 

69 if result.has_outliers and result.outlier_scatter_data is not None 

70 ] 

71 

72 if IS_TRACE: 

73 msg = ( 

74 f"Creating TimeSeriesPlot for {title} with " 

75 f"{len(self.info.data)} data series, " 

76 f"x_values: {self.info.x_labels}, " 

77 f"legend_labels: {self.info.legend_labels}, " 

78 f"scatter_data points: {[scatter_data if len(scatter_data) > 0 else "N/A"]}" 

79 f"data: {self.info.data}" 

80 ) 

81 LOG().trace(msg) 

82 

83 grapher = Plotter( 

84 title=title, 

85 x_label=x_label, 

86 y_label=y_label, 

87 data=self.info.data, 

88 scatter_data=scatter_data if len(scatter_data) > 0 else None, 

89 x_values=self.info.x_labels, 

90 legend_labels=self.info.legend_labels, 

91 ) 

92 

93 return grapher.create()