From 791f3d4af9ad7ff485dc4158c2c3f7078935a9b7 Mon Sep 17 00:00:00 2001 From: emb4 Date: Wed, 19 Jul 2023 16:05:47 +0900 Subject: [PATCH 01/19] Added the ability to create histograms for callbacks. --- src/caret_analyze/plot/plot_facade.py | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/caret_analyze/plot/plot_facade.py b/src/caret_analyze/plot/plot_facade.py index da4e693c7..e28cbe228 100644 --- a/src/caret_analyze/plot/plot_facade.py +++ b/src/caret_analyze/plot/plot_facade.py @@ -26,6 +26,10 @@ from .visualize_lib import VisualizeLibFactory from ..runtime import (Application, CallbackBase, CallbackGroup, Communication, Executor, Node, Path, Publisher, Subscription) +from bokeh.plotting import Figure, show +from caret_analyze.record import Latency +from numpy import histogram +from bokeh.models import HoverTool logger = getLogger(__name__) @@ -273,3 +277,23 @@ def create_message_flow_plot( target_path, visualize_lib, granularity, treat_drop_as_delay, lstrip_s, rstrip_s ) return plot + + @staticmethod + def create_latency_histgram_plot( + target_object: CallbackBase + ) -> Figure: + + latency_records = Latency(target_object.to_records()) + latencies = [d.data['latency'] for d in latency_records.to_records()] + + hist, bins = histogram(latencies, 20) + + plot = Figure(title="histgram", x_axis_label='x', y_axis_label='y') + quad = plot.quad(top=hist, bottom=0, left=bins[:-1], right=bins[1:], line_color='white', alpha=0.5, legend_label=target_object.callback_name) + plot.legend.title = 'Legend' + plot.legend.location = 'top_right' + plot.legend.label_text_font_size = '12pt' + hover = HoverTool(tooltips=[("x", '@left'), ("y", "@top")], renderers=[quad]) + plot.add_tools(hover) + show(plot) + return plot From 48db2fa5f9eab45be5db31339c2b5291c14fce32 Mon Sep 17 00:00:00 2001 From: emb4 Date: Mon, 24 Jul 2023 09:24:47 +0900 Subject: [PATCH 02/19] The process of creating histograms has been moved to Bokeh. --- src/caret_analyze/plot/plot_facade.py | 36 +++++++++++-------- .../plot/visualize_lib/bokeh/bokeh.py | 25 ++++++++++++- 2 files changed, 46 insertions(+), 15 deletions(-) diff --git a/src/caret_analyze/plot/plot_facade.py b/src/caret_analyze/plot/plot_facade.py index e28cbe228..2d8135750 100644 --- a/src/caret_analyze/plot/plot_facade.py +++ b/src/caret_analyze/plot/plot_facade.py @@ -278,22 +278,30 @@ def create_message_flow_plot( ) return plot + # @staticmethod + # def create_latency_histgram_plot( + # target_object: CallbackBase + # ) -> Figure: + + # latency_records = Latency(target_object.to_records()) + # latencies = [d.data['latency'] for d in latency_records.to_records()] + + # hist, bins = histogram(latencies, 20) + + # plot = Figure(title="histgram", x_axis_label='x', y_axis_label='y') + # quad = plot.quad(top=hist, bottom=0, left=bins[:-1], right=bins[1:], line_color='white', alpha=0.5, legend_label=target_object.callback_name) + # plot.legend.title = 'Legend' + # plot.legend.location = 'top_right' + # plot.legend.label_text_font_size = '12pt' + # hover = HoverTool(tooltips=[("x", '@left'), ("y", "@top")], renderers=[quad]) + # plot.add_tools(hover) + # show(plot) + # return plot + @staticmethod def create_latency_histgram_plot( target_object: CallbackBase ) -> Figure: - latency_records = Latency(target_object.to_records()) - latencies = [d.data['latency'] for d in latency_records.to_records()] - - hist, bins = histogram(latencies, 20) - - plot = Figure(title="histgram", x_axis_label='x', y_axis_label='y') - quad = plot.quad(top=hist, bottom=0, left=bins[:-1], right=bins[1:], line_color='white', alpha=0.5, legend_label=target_object.callback_name) - plot.legend.title = 'Legend' - plot.legend.location = 'top_right' - plot.legend.label_text_font_size = '12pt' - hover = HoverTool(tooltips=[("x", '@left'), ("y", "@top")], renderers=[quad]) - plot.add_tools(hover) - show(plot) - return plot + visualize_lib = VisualizeLibFactory.create_instance() + return visualize_lib.histgram(latency_records.to_records(), target_object.callback_name) \ No newline at end of file diff --git a/src/caret_analyze/plot/visualize_lib/bokeh/bokeh.py b/src/caret_analyze/plot/visualize_lib/bokeh/bokeh.py index 7ade5d5b5..4aa990fd3 100644 --- a/src/caret_analyze/plot/visualize_lib/bokeh/bokeh.py +++ b/src/caret_analyze/plot/visualize_lib/bokeh/bokeh.py @@ -28,6 +28,12 @@ from ...metrics_base import MetricsBase from ....runtime import CallbackBase, CallbackGroup, Communication, Path, Publisher, Subscription +from bokeh.plotting import Figure, show +from caret_analyze.record import Latency +from numpy import histogram +from bokeh.models import HoverTool +from ....record.interface import RecordsInterface + TimeSeriesTypes = CallbackBase | Communication | (Publisher | Subscription) logger = getLogger(__name__) @@ -143,7 +149,7 @@ def timeseries( xaxis_type : str Type of x-axis of the line graph to be plotted. "system_time", "index", or "sim_time" can be specified. - The default is "system_time". + The default is "systeadd_toolsm_time". ywheel_zoom : bool If True, the drawn graph can be expanded in the y-axis direction by the mouse wheel. @@ -159,3 +165,20 @@ def timeseries( """ timeseries = BokehTimeSeries(metrics, xaxis_type, ywheel_zoom, full_legends) return timeseries.create_figure() + + def histgram( + self, + metrics: list[RecordsInterface], + callback_name: str + ) -> Figure: + latencies = [d.data['latency'] for d in metrics] + hist, bins = histogram(latencies, 20) + plot = Figure(title='histgram', x_axis_label='x', y_axis_label='y') + quad = plot.quad(top=hist, bottom=0, left=bins[:-1], right=bins[1:], line_color='white', alpha=0.5, legend_label=callback_name) + plot.legend.title = 'Legend' + plot.legend.location = 'top_right' + plot.legend.label_text_font_size = '12pt' + hover = HoverTool(tooltips=[('x', '@left'), ('y', '@top')], renderers=[quad]) + plot.add_tools(hover) + show(plot) + return Figure() \ No newline at end of file From 42ffda3b41fd6e624406124ffc9e83c80d0d5166 Mon Sep 17 00:00:00 2001 From: emb4 Date: Mon, 24 Jul 2023 10:21:41 +0900 Subject: [PATCH 03/19] update bokeh.py --- src/caret_analyze/plot/visualize_lib/bokeh/bokeh.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/caret_analyze/plot/visualize_lib/bokeh/bokeh.py b/src/caret_analyze/plot/visualize_lib/bokeh/bokeh.py index 4aa990fd3..d0d16a785 100644 --- a/src/caret_analyze/plot/visualize_lib/bokeh/bokeh.py +++ b/src/caret_analyze/plot/visualize_lib/bokeh/bokeh.py @@ -149,7 +149,7 @@ def timeseries( xaxis_type : str Type of x-axis of the line graph to be plotted. "system_time", "index", or "sim_time" can be specified. - The default is "systeadd_toolsm_time". + The default is "system_time". ywheel_zoom : bool If True, the drawn graph can be expanded in the y-axis direction by the mouse wheel. From caa9fb3dd0a40905bb2c3f4427d31d31c921c799 Mon Sep 17 00:00:00 2001 From: emb4 Date: Fri, 4 Aug 2023 13:33:53 +0900 Subject: [PATCH 04/19] Temporary push for source code verification --- src/caret_analyze/plot/histogram/__init__.py | 6 +- .../plot/histogram/histogram_plot.py | 122 ++++++++++++++++++ .../plot/histogram/histogram_plot_factory.py | 85 ++++++++++++ src/caret_analyze/plot/plot_facade.py | 97 +++++++++++++- .../plot/visualize_lib/bokeh/bokeh.py | 15 ++- .../visualize_lib/visualize_lib_interface.py | 10 ++ 6 files changed, 322 insertions(+), 13 deletions(-) create mode 100644 src/caret_analyze/plot/histogram/histogram_plot.py create mode 100644 src/caret_analyze/plot/histogram/histogram_plot_factory.py diff --git a/src/caret_analyze/plot/histogram/__init__.py b/src/caret_analyze/plot/histogram/__init__.py index 83306a1da..22bf3164d 100644 --- a/src/caret_analyze/plot/histogram/__init__.py +++ b/src/caret_analyze/plot/histogram/__init__.py @@ -14,8 +14,12 @@ from .histogram import ResponseTimeHistPlot from .histogram_factory import ResponseTimeHistPlotFactory +from .histogram_plot_factory import HistogramPlotFactory +from .histogram_plot import HistogramPlot __all__ = [ 'ResponseTimeHistPlot', - 'ResponseTimeHistPlotFactory' + 'ResponseTimeHistPlotFactory', + 'HistogramPlotFactory', + 'HistogramPlot' ] diff --git a/src/caret_analyze/plot/histogram/histogram_plot.py b/src/caret_analyze/plot/histogram/histogram_plot.py new file mode 100644 index 000000000..6f56d7e78 --- /dev/null +++ b/src/caret_analyze/plot/histogram/histogram_plot.py @@ -0,0 +1,122 @@ +# Copyright 2021 Research Institute of Systems Planning, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from __future__ import annotations + +from bokeh.plotting import Figure + +import pandas as pd + +from ..metrics_base import MetricsBase +from ..plot_base import PlotBase +from ..visualize_lib import VisualizeLibInterface +from ...exceptions import UnsupportedTypeError +from ...runtime import CallbackBase, Communication +from caret_analyze.record import Frequency, Latency, Period + +HistogramTypes = CallbackBase | Communication +hist_types = Frequency | Latency | Period + +class HistogramPlot(PlotBase): + """Class that provides API for timeseries data.""" + + def __init__( + self, + metrics: hist_types, + visualize_lib: VisualizeLibInterface, + callback_name: str, + data_type: str + ) -> None: + self._metrics = metrics + self._visualize_lib = visualize_lib + self._callback_name = callback_name + self._data_type = data_type + + def to_dataframe(self, xaxis_type: str = 'system_time') -> pd.DataFrame: + """ + Get time series data for each object in pandas DataFrame format. + + Parameters + ---------- + xaxis_type : str + Type of time for timestamp. + "system_time", "index", or "sim_time" can be specified, by default "system_time". + + Raises + ------ + UnsupportedTypeError + Argument xaxis_type is not "system_time", "index", or "sim_time". + + Notes + ----- + xaxis_type "system_time" and "index" return the same DataFrame. + + """ + self._validate_xaxis_type(xaxis_type) + return self._metrics.to_dataframe(xaxis_type) + + def figure( + self, + xaxis_type: str | None = None, + ywheel_zoom: bool | None = None, + full_legends: bool | None = None + ) -> Figure: + """ + Get a timeseries graph for each object using the bokeh library. + + Parameters + ---------- + xaxis_type : str + Type of x-axis of the line graph to be plotted. + "system_time", "index", or "sim_time" can be specified, by default "system_time". + ywheel_zoom : bool + If True, the drawn graph can be expanded in the y-axis direction + by the mouse wheel, by default True. + full_legends : bool + If True, all legends are drawn + even if the number of legends exceeds the threshold, by default False. + + Returns + ------- + bokeh.plotting.Figure + + Raises + ------ + UnsupportedTypeError + Argument xaxis_type is not "system_time", "index", or "sim_time". + + """ + # Set default value + xaxis_type = xaxis_type or 'system_time' + ywheel_zoom = ywheel_zoom if ywheel_zoom is not None else True + full_legends = full_legends if full_legends is not None else False + + # Validate + self._validate_xaxis_type(xaxis_type) + + # return self._visualize_lib.histogram( + # self._metrics, + # xaxis_type, + # ywheel_zoom, + # full_legends + # ) + + return self._visualize_lib.histogram(self._metrics.to_records(), self._callback_name, self._data_type) + + def _validate_xaxis_type(self, xaxis_type: str) -> None: + if xaxis_type not in ['system_time', 'sim_time', 'index']: + raise UnsupportedTypeError( + f'Unsupported xaxis_type. xaxis_type = {xaxis_type}. ' + 'supported xaxis_type: [system_time/sim_time/index]' + ) diff --git a/src/caret_analyze/plot/histogram/histogram_plot_factory.py b/src/caret_analyze/plot/histogram/histogram_plot_factory.py new file mode 100644 index 000000000..97f0dabce --- /dev/null +++ b/src/caret_analyze/plot/histogram/histogram_plot_factory.py @@ -0,0 +1,85 @@ +# Copyright 2021 Research Institute of Systems Planning, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from __future__ import annotations + +from collections.abc import Sequence + +from .histogram_plot import HistogramPlot +from ..metrics_base import MetricsBase +from ..visualize_lib import VisualizeLibInterface +from ...common import type_check_decorator +from ...exceptions import UnsupportedTypeError +from ...runtime import CallbackBase, Communication +from caret_analyze.record import Frequency, Latency, Period + +# TimeSeriesPlotTypes = CallbackBase | Communication | (Publisher | Subscription) +HistogramPlotTypes = CallbackBase | Communication + + +class HistogramPlotFactory: + """Factory class to create an instance of TimeSeriesPlot.""" + + @staticmethod + # @type_check_decorator + def create_instance( + target_objects: HistogramPlotTypes, + # target_objects: Sequence[HistogramPlotTypes], + metrics: str, + visualize_lib: VisualizeLibInterface + ) -> HistogramPlot: + """ + Create an instance of TimeSeriesPlot. + + Parameters + ---------- + target_objects : Sequence[TimeSeriesPlotTypes] + TimeSeriesPlotTypes = CallbackBase | Communication | (Publisher | Subscription) + metrics : str + Metrics for timeseries data. + supported metrics: [frequency/latency/period] + visualize_lib : VisualizeLibInterface + Instance of VisualizeLibInterface used for visualization. + + Returns + ------- + TimeSeriesPlot + + Raises + ------ + UnsupportedTypeError + Argument metrics is not "frequency", "latency", or "period". + + """ + metrics_: Frequency | Latency | Period + callback_name = target_objects.callback_name + # Ignore the mypy type check because type_check_decorator is applied. + # metrics_ = Latency(target_objects.to_records()) # type: ignore + # return HistogramPlot(metrics_, visualize_lib) + + if metrics == 'frequency': + metrics_ = Frequency(target_objects.to_records()) + return HistogramPlot(metrics_, visualize_lib, callback_name, metrics) + elif metrics == 'latency': + # Ignore the mypy type check because type_check_decorator is applied. + metrics_ = Latency(target_objects.to_records()) # type: ignore + return HistogramPlot(metrics_, visualize_lib, callback_name, metrics) + elif metrics == 'period': + metrics_ = Period(target_objects.to_records()) + return HistogramPlot(metrics_, visualize_lib, callback_name, metrics) + else: + raise UnsupportedTypeError( + 'Unsupported metrics specified. ' + 'Supported metrics: [frequency/latency/period]' + ) diff --git a/src/caret_analyze/plot/plot_facade.py b/src/caret_analyze/plot/plot_facade.py index 2d8135750..a7c3fba08 100644 --- a/src/caret_analyze/plot/plot_facade.py +++ b/src/caret_analyze/plot/plot_facade.py @@ -18,7 +18,7 @@ from logging import getLogger from .callback_scheduling import CallbackSchedulingPlot, CallbackSchedulingPlotFactory -from .histogram import ResponseTimeHistPlot, ResponseTimeHistPlotFactory +from .histogram import ResponseTimeHistPlot, ResponseTimeHistPlotFactory, HistogramPlotFactory from .message_flow import MessageFlowPlot, MessageFlowPlotFactory from .plot_base import PlotBase from .stacked_bar import StackedBarPlot, StackedBarPlotFactory @@ -34,6 +34,7 @@ logger = getLogger(__name__) TimeSeriesTypes = CallbackBase | Communication | Publisher | Subscription +HistogramTypes = CallbackBase | Communication CallbackSchedTypes = (Application | Executor | Path | Node | CallbackGroup | Collection[CallbackGroup]) @@ -298,10 +299,94 @@ def create_message_flow_plot( # show(plot) # return plot + # @staticmethod + # def create_latency_histgram_plot( + # target_object: CallbackBase + # ) -> Figure: + # latency_records = Latency(target_object.to_records()) + # visualize_lib = VisualizeLibFactory.create_instance() + # return visualize_lib.histgram(latency_records.to_records(), target_object.callback_name) + @staticmethod - def create_latency_histgram_plot( - target_object: CallbackBase - ) -> Figure: - latency_records = Latency(target_object.to_records()) + def create_frequency_histogram_plot( + target_objects: HistogramTypes + ) -> PlotBase: + """ + Get frequency histogram plot instance. + + Parameters + ---------- + target_objects : Collection[TimeSeriesTypes] + HistogramTypes = CallbackBase | Communication + Instances that are the sources of the plotting. + This also accepts multiple inputs by unpacking. + + Returns + ------- + PlotBase + + """ visualize_lib = VisualizeLibFactory.create_instance() - return visualize_lib.histgram(latency_records.to_records(), target_object.callback_name) \ No newline at end of file + # plot = HistogramPlotFactory.create_instance( + # parse_collection_or_unpack(target_objects), 'latency', visualize_lib + # ) + plot = HistogramPlotFactory.create_instance( + target_objects, 'frequency', visualize_lib + ) + return plot + + @staticmethod + def create_latency_histogram_plot( + target_objects: HistogramTypes + ) -> PlotBase: + """ + Get latency histogram plot instance. + + Parameters + ---------- + target_objects : Collection[TimeSeriesTypes] + HistogramTypes = CallbackBase | Communication + Instances that are the sources of the plotting. + This also accepts multiple inputs by unpacking. + + Returns + ------- + PlotBase + + """ + visualize_lib = VisualizeLibFactory.create_instance() + # plot = HistogramPlotFactory.create_instance( + # parse_collection_or_unpack(target_objects), 'latency', visualize_lib + # ) + plot = HistogramPlotFactory.create_instance( + target_objects, 'latency', visualize_lib + ) + return plot + + @staticmethod + def create_period_histogram_plot( + target_objects: HistogramTypes + ) -> PlotBase: + """ + Get period histogram plot instance. + + Parameters + ---------- + target_objects : Collection[TimeSeriesTypes] + HistogramTypes = CallbackBase | Communication + Instances that are the sources of the plotting. + This also accepts multiple inputs by unpacking. + + Returns + ------- + PlotBase + + """ + visualize_lib = VisualizeLibFactory.create_instance() + # plot = HistogramPlotFactory.create_instance( + # parse_collection_or_unpack(target_objects), 'latency', visualize_lib + # ) + plot = HistogramPlotFactory.create_instance( + target_objects, 'period', visualize_lib + ) + return plot \ No newline at end of file diff --git a/src/caret_analyze/plot/visualize_lib/bokeh/bokeh.py b/src/caret_analyze/plot/visualize_lib/bokeh/bokeh.py index d0d16a785..3c7bb97d8 100644 --- a/src/caret_analyze/plot/visualize_lib/bokeh/bokeh.py +++ b/src/caret_analyze/plot/visualize_lib/bokeh/bokeh.py @@ -166,19 +166,22 @@ def timeseries( timeseries = BokehTimeSeries(metrics, xaxis_type, ywheel_zoom, full_legends) return timeseries.create_figure() - def histgram( + def histogram( self, metrics: list[RecordsInterface], - callback_name: str + callback_name: str, + data_type: str ) -> Figure: - latencies = [d.data['latency'] for d in metrics] + # latencies = [d.data['period'] for d in metrics] + latencies = [d.data[data_type] for d in metrics] hist, bins = histogram(latencies, 20) - plot = Figure(title='histgram', x_axis_label='x', y_axis_label='y') + plot = Figure(title=data_type+' histogram', x_axis_label='x', y_axis_label='y') quad = plot.quad(top=hist, bottom=0, left=bins[:-1], right=bins[1:], line_color='white', alpha=0.5, legend_label=callback_name) plot.legend.title = 'Legend' plot.legend.location = 'top_right' plot.legend.label_text_font_size = '12pt' hover = HoverTool(tooltips=[('x', '@left'), ('y', '@top')], renderers=[quad]) plot.add_tools(hover) - show(plot) - return Figure() \ No newline at end of file + # show(plot) + # return Figure() + return plot \ No newline at end of file diff --git a/src/caret_analyze/plot/visualize_lib/visualize_lib_interface.py b/src/caret_analyze/plot/visualize_lib/visualize_lib_interface.py index 322b7480b..cf964dc75 100644 --- a/src/caret_analyze/plot/visualize_lib/visualize_lib_interface.py +++ b/src/caret_analyze/plot/visualize_lib/visualize_lib_interface.py @@ -22,6 +22,8 @@ from ..metrics_base import MetricsBase from ...runtime import CallbackBase, CallbackGroup, Communication, Path, Publisher, Subscription +from ...record.interface import RecordsInterface + TimeSeriesTypes = CallbackBase | Communication | (Publisher | Subscription) @@ -86,3 +88,11 @@ def stacked_bar( case: str, ) -> Figure: raise NotImplementedError() + + def histogram( + self, + metrics: list[RecordsInterface], + callback_name: str, + data_type: str + ) -> Figure: + raise NotImplementedError() From bf0447e1d6955c8db9a07a689b67710e563e1773 Mon Sep 17 00:00:00 2001 From: emb4 Date: Wed, 16 Aug 2023 11:29:28 +0900 Subject: [PATCH 05/19] Push for code confirmation. --- .../plot/histogram/histogram_plot.py | 4 ++-- .../plot/histogram/histogram_plot_factory.py | 20 ++++++++++++++----- src/caret_analyze/plot/plot_facade.py | 13 +++++++----- .../plot/visualize_lib/bokeh/bokeh.py | 14 +++++++++---- 4 files changed, 35 insertions(+), 16 deletions(-) diff --git a/src/caret_analyze/plot/histogram/histogram_plot.py b/src/caret_analyze/plot/histogram/histogram_plot.py index 6f56d7e78..b1538834d 100644 --- a/src/caret_analyze/plot/histogram/histogram_plot.py +++ b/src/caret_analyze/plot/histogram/histogram_plot.py @@ -26,7 +26,7 @@ from caret_analyze.record import Frequency, Latency, Period HistogramTypes = CallbackBase | Communication -hist_types = Frequency | Latency | Period +hist_types = list[Frequency | Latency | Period] class HistogramPlot(PlotBase): """Class that provides API for timeseries data.""" @@ -112,7 +112,7 @@ def figure( # full_legends # ) - return self._visualize_lib.histogram(self._metrics.to_records(), self._callback_name, self._data_type) + return self._visualize_lib.histogram(self._metrics, self._callback_name, self._data_type) def _validate_xaxis_type(self, xaxis_type: str) -> None: if xaxis_type not in ['system_time', 'sim_time', 'index']: diff --git a/src/caret_analyze/plot/histogram/histogram_plot_factory.py b/src/caret_analyze/plot/histogram/histogram_plot_factory.py index 97f0dabce..bbfe44588 100644 --- a/src/caret_analyze/plot/histogram/histogram_plot_factory.py +++ b/src/caret_analyze/plot/histogram/histogram_plot_factory.py @@ -34,8 +34,8 @@ class HistogramPlotFactory: @staticmethod # @type_check_decorator def create_instance( - target_objects: HistogramPlotTypes, - # target_objects: Sequence[HistogramPlotTypes], + # target_objects: HistogramPlotTypes, + target_objects: Sequence[HistogramPlotTypes], metrics: str, visualize_lib: VisualizeLibInterface ) -> HistogramPlot: @@ -62,18 +62,28 @@ def create_instance( Argument metrics is not "frequency", "latency", or "period". """ - metrics_: Frequency | Latency | Period - callback_name = target_objects.callback_name + metrics_: list[Frequency | Latency | Period] = [] + callback_name = target_objects[0].callback_name + # target_objects = target_objects[0] # Ignore the mypy type check because type_check_decorator is applied. # metrics_ = Latency(target_objects.to_records()) # type: ignore # return HistogramPlot(metrics_, visualize_lib) + + + #mertix_ をターゲットオブジェクトが複数ある場合を想定して、metrix_配列を複数作る + #histgram_plotはmetrix_配列を受け取る + # + #引数をそれぞれ変更する if metrics == 'frequency': metrics_ = Frequency(target_objects.to_records()) return HistogramPlot(metrics_, visualize_lib, callback_name, metrics) elif metrics == 'latency': # Ignore the mypy type check because type_check_decorator is applied. - metrics_ = Latency(target_objects.to_records()) # type: ignore + # metrics_ = Latency(target_objects.to_records()) # type: ignore + for target_object in target_objects: + temp = Latency(target_object.to_records()) + metrics_.append(temp) return HistogramPlot(metrics_, visualize_lib, callback_name, metrics) elif metrics == 'period': metrics_ = Period(target_objects.to_records()) diff --git a/src/caret_analyze/plot/plot_facade.py b/src/caret_analyze/plot/plot_facade.py index a7c3fba08..a55959791 100644 --- a/src/caret_analyze/plot/plot_facade.py +++ b/src/caret_analyze/plot/plot_facade.py @@ -31,6 +31,8 @@ from numpy import histogram from bokeh.models import HoverTool +from collections.abc import Sequence + logger = getLogger(__name__) TimeSeriesTypes = CallbackBase | Communication | Publisher | Subscription @@ -337,7 +339,8 @@ def create_frequency_histogram_plot( @staticmethod def create_latency_histogram_plot( - target_objects: HistogramTypes + *target_objects: HistogramTypes + # target_objects: Sequence[HistogramTypes] ) -> PlotBase: """ Get latency histogram plot instance. @@ -355,12 +358,12 @@ def create_latency_histogram_plot( """ visualize_lib = VisualizeLibFactory.create_instance() - # plot = HistogramPlotFactory.create_instance( - # parse_collection_or_unpack(target_objects), 'latency', visualize_lib - # ) plot = HistogramPlotFactory.create_instance( - target_objects, 'latency', visualize_lib + parse_collection_or_unpack(target_objects), 'latency', visualize_lib ) + # plot = HistogramPlotFactory.create_instance( + # target_objects, 'latency', visualize_lib + # ) return plot @staticmethod diff --git a/src/caret_analyze/plot/visualize_lib/bokeh/bokeh.py b/src/caret_analyze/plot/visualize_lib/bokeh/bokeh.py index 3c7bb97d8..720887eca 100644 --- a/src/caret_analyze/plot/visualize_lib/bokeh/bokeh.py +++ b/src/caret_analyze/plot/visualize_lib/bokeh/bokeh.py @@ -169,19 +169,25 @@ def timeseries( def histogram( self, metrics: list[RecordsInterface], + # metrics: RecordsInterface, callback_name: str, data_type: str ) -> Figure: - # latencies = [d.data['period'] for d in metrics] - latencies = [d.data[data_type] for d in metrics] + #for文で配列の長さ分繰り返すように実装を変更、複数の図が重なって出る感じに + + for _metrics in metrics: + latencies = [d.data[data_type] for d in _metrics] hist, bins = histogram(latencies, 20) plot = Figure(title=data_type+' histogram', x_axis_label='x', y_axis_label='y') quad = plot.quad(top=hist, bottom=0, left=bins[:-1], right=bins[1:], line_color='white', alpha=0.5, legend_label=callback_name) + + # latencies = [d.data[data_type] for d in metrics] + # hist, bins = histogram(latencies, 20) + # plot = Figure(title=data_type+' histogram', x_axis_label='x', y_axis_label='y') + # quad = plot.quad(top=hist, bottom=0, left=bins[:-1], right=bins[1:], line_color='white', alpha=0.5, legend_label=callback_name) plot.legend.title = 'Legend' plot.legend.location = 'top_right' plot.legend.label_text_font_size = '12pt' hover = HoverTool(tooltips=[('x', '@left'), ('y', '@top')], renderers=[quad]) plot.add_tools(hover) - # show(plot) - # return Figure() return plot \ No newline at end of file From ae88a7f487cb46833ba42424043adbbe34706743 Mon Sep 17 00:00:00 2001 From: emb4 Date: Thu, 17 Aug 2023 12:01:26 +0900 Subject: [PATCH 06/19] Push for code confirmation. --- src/caret_analyze/plot/visualize_lib/bokeh/bokeh.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/caret_analyze/plot/visualize_lib/bokeh/bokeh.py b/src/caret_analyze/plot/visualize_lib/bokeh/bokeh.py index 720887eca..b6d335b70 100644 --- a/src/caret_analyze/plot/visualize_lib/bokeh/bokeh.py +++ b/src/caret_analyze/plot/visualize_lib/bokeh/bokeh.py @@ -174,9 +174,12 @@ def histogram( data_type: str ) -> Figure: #for文で配列の長さ分繰り返すように実装を変更、複数の図が重なって出る感じに + latencies = [] for _metrics in metrics: - latencies = [d.data[data_type] for d in _metrics] + # latencies = [d.data[data_type] for d in _metrics.to_records()] + latencie = [d.data[data_type] for d in _metrics.to_records()] + latencies.append(latencie) hist, bins = histogram(latencies, 20) plot = Figure(title=data_type+' histogram', x_axis_label='x', y_axis_label='y') quad = plot.quad(top=hist, bottom=0, left=bins[:-1], right=bins[1:], line_color='white', alpha=0.5, legend_label=callback_name) From 34b6da942e51f3e19ff6bed49cecb1da0626a4ad Mon Sep 17 00:00:00 2001 From: emb4 Date: Wed, 23 Aug 2023 17:02:11 +0900 Subject: [PATCH 07/19] The error that occurred in pytest has been resolved. Signed-off-by: emb4 --- src/caret_analyze/plot/histogram/__init__.py | 2 +- .../plot/histogram/histogram_plot.py | 18 ++---- .../plot/histogram/histogram_plot_factory.py | 34 ++++------- src/caret_analyze/plot/plot_facade.py | 60 ++++--------------- .../plot/visualize_lib/bokeh/bokeh.py | 51 ++++++++-------- .../visualize_lib/visualize_lib_interface.py | 9 ++- src/caret_analyze/runtime/path.py | 6 +- 7 files changed, 60 insertions(+), 120 deletions(-) diff --git a/src/caret_analyze/plot/histogram/__init__.py b/src/caret_analyze/plot/histogram/__init__.py index 22bf3164d..fb8e1ad6d 100644 --- a/src/caret_analyze/plot/histogram/__init__.py +++ b/src/caret_analyze/plot/histogram/__init__.py @@ -14,8 +14,8 @@ from .histogram import ResponseTimeHistPlot from .histogram_factory import ResponseTimeHistPlotFactory -from .histogram_plot_factory import HistogramPlotFactory from .histogram_plot import HistogramPlot +from .histogram_plot_factory import HistogramPlotFactory __all__ = [ 'ResponseTimeHistPlot', diff --git a/src/caret_analyze/plot/histogram/histogram_plot.py b/src/caret_analyze/plot/histogram/histogram_plot.py index b1538834d..2e287ec51 100644 --- a/src/caret_analyze/plot/histogram/histogram_plot.py +++ b/src/caret_analyze/plot/histogram/histogram_plot.py @@ -16,18 +16,19 @@ from bokeh.plotting import Figure +from caret_analyze.record import Frequency, Latency, Period + import pandas as pd -from ..metrics_base import MetricsBase from ..plot_base import PlotBase from ..visualize_lib import VisualizeLibInterface from ...exceptions import UnsupportedTypeError from ...runtime import CallbackBase, Communication -from caret_analyze.record import Frequency, Latency, Period HistogramTypes = CallbackBase | Communication hist_types = list[Frequency | Latency | Period] + class HistogramPlot(PlotBase): """Class that provides API for timeseries data.""" @@ -35,12 +36,12 @@ def __init__( self, metrics: hist_types, visualize_lib: VisualizeLibInterface, - callback_name: str, + callback_names: list[str], data_type: str ) -> None: self._metrics = metrics self._visualize_lib = visualize_lib - self._callback_name = callback_name + self._callback_names = callback_names self._data_type = data_type def to_dataframe(self, xaxis_type: str = 'system_time') -> pd.DataFrame: @@ -105,14 +106,7 @@ def figure( # Validate self._validate_xaxis_type(xaxis_type) - # return self._visualize_lib.histogram( - # self._metrics, - # xaxis_type, - # ywheel_zoom, - # full_legends - # ) - - return self._visualize_lib.histogram(self._metrics, self._callback_name, self._data_type) + return self._visualize_lib.histogram(self._metrics, self._callback_names, self._data_type) def _validate_xaxis_type(self, xaxis_type: str) -> None: if xaxis_type not in ['system_time', 'sim_time', 'index']: diff --git a/src/caret_analyze/plot/histogram/histogram_plot_factory.py b/src/caret_analyze/plot/histogram/histogram_plot_factory.py index bbfe44588..840dfccae 100644 --- a/src/caret_analyze/plot/histogram/histogram_plot_factory.py +++ b/src/caret_analyze/plot/histogram/histogram_plot_factory.py @@ -16,15 +16,14 @@ from collections.abc import Sequence +from caret_analyze.record import Frequency, Latency, Period + from .histogram_plot import HistogramPlot -from ..metrics_base import MetricsBase from ..visualize_lib import VisualizeLibInterface -from ...common import type_check_decorator +# from ...common import type_check_decorator from ...exceptions import UnsupportedTypeError from ...runtime import CallbackBase, Communication -from caret_analyze.record import Frequency, Latency, Period -# TimeSeriesPlotTypes = CallbackBase | Communication | (Publisher | Subscription) HistogramPlotTypes = CallbackBase | Communication @@ -63,31 +62,24 @@ def create_instance( """ metrics_: list[Frequency | Latency | Period] = [] - callback_name = target_objects[0].callback_name - # target_objects = target_objects[0] - # Ignore the mypy type check because type_check_decorator is applied. - # metrics_ = Latency(target_objects.to_records()) # type: ignore - # return HistogramPlot(metrics_, visualize_lib) - + callback_names = [obj.callback_name for obj in target_objects] - #mertix_ をターゲットオブジェクトが複数ある場合を想定して、metrix_配列を複数作る - #histgram_plotはmetrix_配列を受け取る - # - #引数をそれぞれ変更する - if metrics == 'frequency': - metrics_ = Frequency(target_objects.to_records()) - return HistogramPlot(metrics_, visualize_lib, callback_name, metrics) + for target_object in target_objects: + temp = Frequency(target_object.to_records()) + metrics_.append(temp) + return HistogramPlot(metrics_, visualize_lib, callback_names, metrics) elif metrics == 'latency': # Ignore the mypy type check because type_check_decorator is applied. - # metrics_ = Latency(target_objects.to_records()) # type: ignore for target_object in target_objects: temp = Latency(target_object.to_records()) metrics_.append(temp) - return HistogramPlot(metrics_, visualize_lib, callback_name, metrics) + return HistogramPlot(metrics_, visualize_lib, callback_names, metrics) elif metrics == 'period': - metrics_ = Period(target_objects.to_records()) - return HistogramPlot(metrics_, visualize_lib, callback_name, metrics) + for target_object in target_objects: + temp = Period(target_object.to_records()) + metrics_.append(temp) + return HistogramPlot(metrics_, visualize_lib, callback_names, metrics) else: raise UnsupportedTypeError( 'Unsupported metrics specified. ' diff --git a/src/caret_analyze/plot/plot_facade.py b/src/caret_analyze/plot/plot_facade.py index a55959791..a9e6aea36 100644 --- a/src/caret_analyze/plot/plot_facade.py +++ b/src/caret_analyze/plot/plot_facade.py @@ -18,7 +18,7 @@ from logging import getLogger from .callback_scheduling import CallbackSchedulingPlot, CallbackSchedulingPlotFactory -from .histogram import ResponseTimeHistPlot, ResponseTimeHistPlotFactory, HistogramPlotFactory +from .histogram import HistogramPlotFactory, ResponseTimeHistPlot, ResponseTimeHistPlotFactory from .message_flow import MessageFlowPlot, MessageFlowPlotFactory from .plot_base import PlotBase from .stacked_bar import StackedBarPlot, StackedBarPlotFactory @@ -26,12 +26,12 @@ from .visualize_lib import VisualizeLibFactory from ..runtime import (Application, CallbackBase, CallbackGroup, Communication, Executor, Node, Path, Publisher, Subscription) -from bokeh.plotting import Figure, show -from caret_analyze.record import Latency -from numpy import histogram -from bokeh.models import HoverTool +# from bokeh.plotting import Figure, show +# from caret_analyze.record import Latency +# from numpy import histogram +# from bokeh.models import HoverTool -from collections.abc import Sequence +# from collections.abc import Sequence logger = getLogger(__name__) @@ -280,34 +280,6 @@ def create_message_flow_plot( target_path, visualize_lib, granularity, treat_drop_as_delay, lstrip_s, rstrip_s ) return plot - - # @staticmethod - # def create_latency_histgram_plot( - # target_object: CallbackBase - # ) -> Figure: - - # latency_records = Latency(target_object.to_records()) - # latencies = [d.data['latency'] for d in latency_records.to_records()] - - # hist, bins = histogram(latencies, 20) - - # plot = Figure(title="histgram", x_axis_label='x', y_axis_label='y') - # quad = plot.quad(top=hist, bottom=0, left=bins[:-1], right=bins[1:], line_color='white', alpha=0.5, legend_label=target_object.callback_name) - # plot.legend.title = 'Legend' - # plot.legend.location = 'top_right' - # plot.legend.label_text_font_size = '12pt' - # hover = HoverTool(tooltips=[("x", '@left'), ("y", "@top")], renderers=[quad]) - # plot.add_tools(hover) - # show(plot) - # return plot - - # @staticmethod - # def create_latency_histgram_plot( - # target_object: CallbackBase - # ) -> Figure: - # latency_records = Latency(target_object.to_records()) - # visualize_lib = VisualizeLibFactory.create_instance() - # return visualize_lib.histgram(latency_records.to_records(), target_object.callback_name) @staticmethod def create_frequency_histogram_plot( @@ -329,18 +301,14 @@ def create_frequency_histogram_plot( """ visualize_lib = VisualizeLibFactory.create_instance() - # plot = HistogramPlotFactory.create_instance( - # parse_collection_or_unpack(target_objects), 'latency', visualize_lib - # ) plot = HistogramPlotFactory.create_instance( - target_objects, 'frequency', visualize_lib + parse_collection_or_unpack(target_objects), 'frequency', visualize_lib ) return plot - + @staticmethod def create_latency_histogram_plot( *target_objects: HistogramTypes - # target_objects: Sequence[HistogramTypes] ) -> PlotBase: """ Get latency histogram plot instance. @@ -361,11 +329,8 @@ def create_latency_histogram_plot( plot = HistogramPlotFactory.create_instance( parse_collection_or_unpack(target_objects), 'latency', visualize_lib ) - # plot = HistogramPlotFactory.create_instance( - # target_objects, 'latency', visualize_lib - # ) return plot - + @staticmethod def create_period_histogram_plot( target_objects: HistogramTypes @@ -386,10 +351,7 @@ def create_period_histogram_plot( """ visualize_lib = VisualizeLibFactory.create_instance() - # plot = HistogramPlotFactory.create_instance( - # parse_collection_or_unpack(target_objects), 'latency', visualize_lib - # ) plot = HistogramPlotFactory.create_instance( - target_objects, 'period', visualize_lib + parse_collection_or_unpack(target_objects), 'period', visualize_lib ) - return plot \ No newline at end of file + return plot diff --git a/src/caret_analyze/plot/visualize_lib/bokeh/bokeh.py b/src/caret_analyze/plot/visualize_lib/bokeh/bokeh.py index b6d335b70..4f55fecf8 100644 --- a/src/caret_analyze/plot/visualize_lib/bokeh/bokeh.py +++ b/src/caret_analyze/plot/visualize_lib/bokeh/bokeh.py @@ -17,23 +17,24 @@ from collections.abc import Sequence from logging import getLogger +from bokeh.models import HoverTool + from bokeh.plotting import Figure +from caret_analyze.record import Frequency, Latency, Period + +from numpy import histogram + from .callback_scheduling import BokehCallbackSched from .message_flow import BokehMessageFlow from .response_time_hist import BokehResponseTimeHist from .stacked_bar import BokehStackedBar from .timeseries import BokehTimeSeries +from .util import ColorSelectorFactory from ..visualize_lib_interface import VisualizeLibInterface from ...metrics_base import MetricsBase from ....runtime import CallbackBase, CallbackGroup, Communication, Path, Publisher, Subscription -from bokeh.plotting import Figure, show -from caret_analyze.record import Latency -from numpy import histogram -from bokeh.models import HoverTool -from ....record.interface import RecordsInterface - TimeSeriesTypes = CallbackBase | Communication | (Publisher | Subscription) logger = getLogger(__name__) @@ -165,32 +166,28 @@ def timeseries( """ timeseries = BokehTimeSeries(metrics, xaxis_type, ywheel_zoom, full_legends) return timeseries.create_figure() - + def histogram( self, - metrics: list[RecordsInterface], - # metrics: RecordsInterface, - callback_name: str, + metrics: list[Frequency | Latency | Period], + callback_names: list[str], data_type: str ) -> Figure: - #for文で配列の長さ分繰り返すように実装を変更、複数の図が重なって出る感じに - latencies = [] - - for _metrics in metrics: - # latencies = [d.data[data_type] for d in _metrics.to_records()] - latencie = [d.data[data_type] for d in _metrics.to_records()] - latencies.append(latencie) - hist, bins = histogram(latencies, 20) plot = Figure(title=data_type+' histogram', x_axis_label='x', y_axis_label='y') - quad = plot.quad(top=hist, bottom=0, left=bins[:-1], right=bins[1:], line_color='white', alpha=0.5, legend_label=callback_name) - - # latencies = [d.data[data_type] for d in metrics] - # hist, bins = histogram(latencies, 20) - # plot = Figure(title=data_type+' histogram', x_axis_label='x', y_axis_label='y') - # quad = plot.quad(top=hist, bottom=0, left=bins[:-1], right=bins[1:], line_color='white', alpha=0.5, legend_label=callback_name) + latencies: list[list[int]] = [m.to_records().get_column_series(data_type) for m in metrics] + color_selector = ColorSelectorFactory.create_instance('unique') + max_value = max(max(latencies, key=lambda x: max(x))) + min_value = min(min(latencies, key=lambda x: min(x))) + + for latency, callback_name in zip(latencies, callback_names): + hist, bins = histogram(latency, 20, (min_value, max_value)) + quad = plot.quad(top=hist, bottom=0, + left=bins[:-1], right=bins[1:], + line_color='white', alpha=0.5, legend_label=callback_name, + color=color_selector.get_color()) + hover = HoverTool(tooltips=[('x', '@left'), ('y', '@top')], renderers=[quad]) + plot.add_tools(hover) plot.legend.title = 'Legend' plot.legend.location = 'top_right' plot.legend.label_text_font_size = '12pt' - hover = HoverTool(tooltips=[('x', '@left'), ('y', '@top')], renderers=[quad]) - plot.add_tools(hover) - return plot \ No newline at end of file + return plot diff --git a/src/caret_analyze/plot/visualize_lib/visualize_lib_interface.py b/src/caret_analyze/plot/visualize_lib/visualize_lib_interface.py index cf964dc75..46ba49807 100644 --- a/src/caret_analyze/plot/visualize_lib/visualize_lib_interface.py +++ b/src/caret_analyze/plot/visualize_lib/visualize_lib_interface.py @@ -20,10 +20,9 @@ from bokeh.plotting import Figure from ..metrics_base import MetricsBase +from ...record import Latency from ...runtime import CallbackBase, CallbackGroup, Communication, Path, Publisher, Subscription -from ...record.interface import RecordsInterface - TimeSeriesTypes = CallbackBase | Communication | (Publisher | Subscription) @@ -88,11 +87,11 @@ def stacked_bar( case: str, ) -> Figure: raise NotImplementedError() - + def histogram( self, - metrics: list[RecordsInterface], - callback_name: str, + metrics: list[Latency], + callback_names: list[str], data_type: str ) -> Figure: raise NotImplementedError() diff --git a/src/caret_analyze/runtime/path.py b/src/caret_analyze/runtime/path.py index 0de8aaedb..6afe4e734 100644 --- a/src/caret_analyze/runtime/path.py +++ b/src/caret_analyze/runtime/path.py @@ -91,11 +91,7 @@ def _to_rename_rule( old_columns: Sequence[str], new_columns: Sequence[str], ): - return { - old_column: new_column - for old_column, new_column - in zip(old_columns, new_columns) - } + return dict(zip(old_columns, new_columns)) class RecordsMerged: From aa7609ebecc7ef16b713c4862d9ba4b6ec420f36 Mon Sep 17 00:00:00 2001 From: emb4 Date: Thu, 31 Aug 2023 09:03:54 +0900 Subject: [PATCH 08/19] Resolved pytest error. --- .../plot/histogram/histogram_plot.py | 22 +++++------ .../plot/histogram/histogram_plot_factory.py | 27 ++++++++----- src/caret_analyze/plot/plot_facade.py | 38 +++++++++++++++++-- .../plot/visualize_lib/bokeh/bokeh.py | 5 ++- .../visualize_lib/visualize_lib_interface.py | 4 +- 5 files changed, 67 insertions(+), 29 deletions(-) diff --git a/src/caret_analyze/plot/histogram/histogram_plot.py b/src/caret_analyze/plot/histogram/histogram_plot.py index 2e287ec51..29c4f2ef2 100644 --- a/src/caret_analyze/plot/histogram/histogram_plot.py +++ b/src/caret_analyze/plot/histogram/histogram_plot.py @@ -44,28 +44,24 @@ def __init__( self._callback_names = callback_names self._data_type = data_type - def to_dataframe(self, xaxis_type: str = 'system_time') -> pd.DataFrame: + def to_dataframe( + self, + xaxis_type: str + ) -> pd.DataFrame: """ - Get time series data for each object in pandas DataFrame format. + Get data in pandas DataFrame format. Parameters ---------- xaxis_type : str Type of time for timestamp. - "system_time", "index", or "sim_time" can be specified, by default "system_time". - - Raises - ------ - UnsupportedTypeError - Argument xaxis_type is not "system_time", "index", or "sim_time". - Notes - ----- - xaxis_type "system_time" and "index" return the same DataFrame. + Returns + ------- + pd.DataFrame """ - self._validate_xaxis_type(xaxis_type) - return self._metrics.to_dataframe(xaxis_type) + raise NotImplementedError() def figure( self, diff --git a/src/caret_analyze/plot/histogram/histogram_plot_factory.py b/src/caret_analyze/plot/histogram/histogram_plot_factory.py index 840dfccae..0c95b2b43 100644 --- a/src/caret_analyze/plot/histogram/histogram_plot_factory.py +++ b/src/caret_analyze/plot/histogram/histogram_plot_factory.py @@ -20,7 +20,7 @@ from .histogram_plot import HistogramPlot from ..visualize_lib import VisualizeLibInterface -# from ...common import type_check_decorator +from ...common import type_check_decorator from ...exceptions import UnsupportedTypeError from ...runtime import CallbackBase, Communication @@ -31,9 +31,8 @@ class HistogramPlotFactory: """Factory class to create an instance of TimeSeriesPlot.""" @staticmethod - # @type_check_decorator + @type_check_decorator def create_instance( - # target_objects: HistogramPlotTypes, target_objects: Sequence[HistogramPlotTypes], metrics: str, visualize_lib: VisualizeLibInterface @@ -62,23 +61,31 @@ def create_instance( """ metrics_: list[Frequency | Latency | Period] = [] - callback_names = [obj.callback_name for obj in target_objects] + # if all([isinstance(obj, CallbackBase) for obj in target_objects]): + # callback_names = [obj.callback_name for obj in target_objects] # type: ignore + # elif all([isinstance(obj, Communication) for obj in target_objects]): + # callback_names = [obj.column_names for obj in target_objects] # type: ignore + callback_names = [ + obj.callback_name if isinstance(obj, CallbackBase) + else obj.column_names[0].split('/')[-1] + for obj in target_objects + ] if metrics == 'frequency': for target_object in target_objects: - temp = Frequency(target_object.to_records()) - metrics_.append(temp) + frequency = Frequency(target_object.to_records()) + metrics_.append(frequency) return HistogramPlot(metrics_, visualize_lib, callback_names, metrics) elif metrics == 'latency': # Ignore the mypy type check because type_check_decorator is applied. for target_object in target_objects: - temp = Latency(target_object.to_records()) - metrics_.append(temp) + latency = Latency(target_object.to_records()) + metrics_.append(latency) return HistogramPlot(metrics_, visualize_lib, callback_names, metrics) elif metrics == 'period': for target_object in target_objects: - temp = Period(target_object.to_records()) - metrics_.append(temp) + period = Period(target_object.to_records()) + metrics_.append(period) return HistogramPlot(metrics_, visualize_lib, callback_names, metrics) else: raise UnsupportedTypeError( diff --git a/src/caret_analyze/plot/plot_facade.py b/src/caret_analyze/plot/plot_facade.py index a9e6aea36..d85cc38e8 100644 --- a/src/caret_analyze/plot/plot_facade.py +++ b/src/caret_analyze/plot/plot_facade.py @@ -70,6 +70,35 @@ def parse_collection_or_unpack( return parsed_target_objects +def parse_collection_or_unpack_for_hist( + target_arg: tuple[Collection[HistogramTypes]] | tuple[HistogramTypes, ...] +) -> list[HistogramTypes]: + """ + Parse target argument. + + To address both cases where the target argument is passed in collection type + or unpacked, this function converts them to the same list format. + + Parameters + ---------- + target_arg : tuple[Collection[HistogramTypes]] | tuple[HistogramTypes, ...] + Target objects. + + Returns + ------- + list[HistogramTypes] + + """ + parsed_target_objects: list[HistogramTypes] + if isinstance(target_arg[0], Collection): + assert len(target_arg) == 1 + parsed_target_objects = list(target_arg[0]) + else: # Unpacked case + parsed_target_objects = list(target_arg) # type: ignore + + return parsed_target_objects + + class Plot: """Facade class for plot.""" @@ -302,7 +331,8 @@ def create_frequency_histogram_plot( """ visualize_lib = VisualizeLibFactory.create_instance() plot = HistogramPlotFactory.create_instance( - parse_collection_or_unpack(target_objects), 'frequency', visualize_lib + parse_collection_or_unpack_for_hist(target_objects), # type: ignore + 'frequency', visualize_lib ) return plot @@ -327,7 +357,8 @@ def create_latency_histogram_plot( """ visualize_lib = VisualizeLibFactory.create_instance() plot = HistogramPlotFactory.create_instance( - parse_collection_or_unpack(target_objects), 'latency', visualize_lib + parse_collection_or_unpack_for_hist(target_objects), # type: ignore + 'latency', visualize_lib ) return plot @@ -352,6 +383,7 @@ def create_period_histogram_plot( """ visualize_lib = VisualizeLibFactory.create_instance() plot = HistogramPlotFactory.create_instance( - parse_collection_or_unpack(target_objects), 'period', visualize_lib + parse_collection_or_unpack_for_hist(target_objects), # type: ignore + 'period', visualize_lib ) return plot diff --git a/src/caret_analyze/plot/visualize_lib/bokeh/bokeh.py b/src/caret_analyze/plot/visualize_lib/bokeh/bokeh.py index 4f55fecf8..17828a8fd 100644 --- a/src/caret_analyze/plot/visualize_lib/bokeh/bokeh.py +++ b/src/caret_analyze/plot/visualize_lib/bokeh/bokeh.py @@ -174,7 +174,10 @@ def histogram( data_type: str ) -> Figure: plot = Figure(title=data_type+' histogram', x_axis_label='x', y_axis_label='y') - latencies: list[list[int]] = [m.to_records().get_column_series(data_type) for m in metrics] + latencies: list[list[int]] = [ + [_ for _ in m.to_records().get_column_series(data_type) if _ is not None] + for m in metrics + ] color_selector = ColorSelectorFactory.create_instance('unique') max_value = max(max(latencies, key=lambda x: max(x))) min_value = min(min(latencies, key=lambda x: min(x))) diff --git a/src/caret_analyze/plot/visualize_lib/visualize_lib_interface.py b/src/caret_analyze/plot/visualize_lib/visualize_lib_interface.py index 46ba49807..dc75c8be6 100644 --- a/src/caret_analyze/plot/visualize_lib/visualize_lib_interface.py +++ b/src/caret_analyze/plot/visualize_lib/visualize_lib_interface.py @@ -20,7 +20,7 @@ from bokeh.plotting import Figure from ..metrics_base import MetricsBase -from ...record import Latency +from ...record import Frequency, Latency, Period from ...runtime import CallbackBase, CallbackGroup, Communication, Path, Publisher, Subscription TimeSeriesTypes = CallbackBase | Communication | (Publisher | Subscription) @@ -90,7 +90,7 @@ def stacked_bar( def histogram( self, - metrics: list[Latency], + metrics: list[Frequency | Latency | Period], callback_names: list[str], data_type: str ) -> Figure: From f4faa59b4e202e83b4f404c954c25c974b07273e Mon Sep 17 00:00:00 2001 From: emb4 Date: Thu, 31 Aug 2023 13:33:47 +0900 Subject: [PATCH 09/19] The points raised in the review have been corrected. Signed-off-by: emb4 --- .../plot/histogram/histogram_plot.py | 10 ++-- .../plot/histogram/histogram_plot_factory.py | 44 +++++--------- src/caret_analyze/plot/plot_facade.py | 60 +------------------ .../plot/visualize_lib/bokeh/bokeh.py | 14 ++--- .../visualize_lib/visualize_lib_interface.py | 4 +- 5 files changed, 29 insertions(+), 103 deletions(-) diff --git a/src/caret_analyze/plot/histogram/histogram_plot.py b/src/caret_analyze/plot/histogram/histogram_plot.py index 29c4f2ef2..3f8897efc 100644 --- a/src/caret_analyze/plot/histogram/histogram_plot.py +++ b/src/caret_analyze/plot/histogram/histogram_plot.py @@ -16,7 +16,7 @@ from bokeh.plotting import Figure -from caret_analyze.record import Frequency, Latency, Period +from caret_analyze.record import Latency import pandas as pd @@ -26,15 +26,15 @@ from ...runtime import CallbackBase, Communication HistogramTypes = CallbackBase | Communication -hist_types = list[Frequency | Latency | Period] +Hist_Types = list[Latency] class HistogramPlot(PlotBase): - """Class that provides API for timeseries data.""" + """Class that provides API for histogram data.""" def __init__( self, - metrics: hist_types, + metrics: Hist_Types, visualize_lib: VisualizeLibInterface, callback_names: list[str], data_type: str @@ -70,7 +70,7 @@ def figure( full_legends: bool | None = None ) -> Figure: """ - Get a timeseries graph for each object using the bokeh library. + Get a histogram graph for each object using the bokeh library. Parameters ---------- diff --git a/src/caret_analyze/plot/histogram/histogram_plot_factory.py b/src/caret_analyze/plot/histogram/histogram_plot_factory.py index 0c95b2b43..8d1fe5c0a 100644 --- a/src/caret_analyze/plot/histogram/histogram_plot_factory.py +++ b/src/caret_analyze/plot/histogram/histogram_plot_factory.py @@ -16,7 +16,7 @@ from collections.abc import Sequence -from caret_analyze.record import Frequency, Latency, Period +from caret_analyze.record import Latency from .histogram_plot import HistogramPlot from ..visualize_lib import VisualizeLibInterface @@ -28,65 +28,49 @@ class HistogramPlotFactory: - """Factory class to create an instance of TimeSeriesPlot.""" + """Factory class to create an instance of HistogramPlot.""" @staticmethod @type_check_decorator def create_instance( target_objects: Sequence[HistogramPlotTypes], - metrics: str, + metrics_name: str, visualize_lib: VisualizeLibInterface ) -> HistogramPlot: """ - Create an instance of TimeSeriesPlot. + Create an instance of HistogramPlot. Parameters ---------- - target_objects : Sequence[TimeSeriesPlotTypes] - TimeSeriesPlotTypes = CallbackBase | Communication | (Publisher | Subscription) - metrics : str - Metrics for timeseries data. + target_objects : Sequence[HistogramPlotTypes] + HistogramPlotTypes = CallbackBase | Communication + metrics_name : str + Metrics for histogramplot data. supported metrics: [frequency/latency/period] visualize_lib : VisualizeLibInterface Instance of VisualizeLibInterface used for visualization. Returns ------- - TimeSeriesPlot + HistogramPlot Raises ------ UnsupportedTypeError - Argument metrics is not "frequency", "latency", or "period". + Argument metrics is not "latency". """ - metrics_: list[Frequency | Latency | Period] = [] - # if all([isinstance(obj, CallbackBase) for obj in target_objects]): - # callback_names = [obj.callback_name for obj in target_objects] # type: ignore - # elif all([isinstance(obj, Communication) for obj in target_objects]): - # callback_names = [obj.column_names for obj in target_objects] # type: ignore + metrics: list[Latency] = [] callback_names = [ obj.callback_name if isinstance(obj, CallbackBase) else obj.column_names[0].split('/')[-1] for obj in target_objects ] - if metrics == 'frequency': - for target_object in target_objects: - frequency = Frequency(target_object.to_records()) - metrics_.append(frequency) - return HistogramPlot(metrics_, visualize_lib, callback_names, metrics) - elif metrics == 'latency': + if metrics_name == 'latency': # Ignore the mypy type check because type_check_decorator is applied. - for target_object in target_objects: - latency = Latency(target_object.to_records()) - metrics_.append(latency) - return HistogramPlot(metrics_, visualize_lib, callback_names, metrics) - elif metrics == 'period': - for target_object in target_objects: - period = Period(target_object.to_records()) - metrics_.append(period) - return HistogramPlot(metrics_, visualize_lib, callback_names, metrics) + metrics = [Latency(target_object.to_records()) for target_object in target_objects] + return HistogramPlot(metrics, visualize_lib, callback_names, metrics_name) else: raise UnsupportedTypeError( 'Unsupported metrics specified. ' diff --git a/src/caret_analyze/plot/plot_facade.py b/src/caret_analyze/plot/plot_facade.py index d85cc38e8..0807964c1 100644 --- a/src/caret_analyze/plot/plot_facade.py +++ b/src/caret_analyze/plot/plot_facade.py @@ -26,12 +26,6 @@ from .visualize_lib import VisualizeLibFactory from ..runtime import (Application, CallbackBase, CallbackGroup, Communication, Executor, Node, Path, Publisher, Subscription) -# from bokeh.plotting import Figure, show -# from caret_analyze.record import Latency -# from numpy import histogram -# from bokeh.models import HoverTool - -# from collections.abc import Sequence logger = getLogger(__name__) @@ -310,32 +304,6 @@ def create_message_flow_plot( ) return plot - @staticmethod - def create_frequency_histogram_plot( - target_objects: HistogramTypes - ) -> PlotBase: - """ - Get frequency histogram plot instance. - - Parameters - ---------- - target_objects : Collection[TimeSeriesTypes] - HistogramTypes = CallbackBase | Communication - Instances that are the sources of the plotting. - This also accepts multiple inputs by unpacking. - - Returns - ------- - PlotBase - - """ - visualize_lib = VisualizeLibFactory.create_instance() - plot = HistogramPlotFactory.create_instance( - parse_collection_or_unpack_for_hist(target_objects), # type: ignore - 'frequency', visualize_lib - ) - return plot - @staticmethod def create_latency_histogram_plot( *target_objects: HistogramTypes @@ -345,7 +313,7 @@ def create_latency_histogram_plot( Parameters ---------- - target_objects : Collection[TimeSeriesTypes] + target_objects : Collection[HistogramTypes] HistogramTypes = CallbackBase | Communication Instances that are the sources of the plotting. This also accepts multiple inputs by unpacking. @@ -361,29 +329,3 @@ def create_latency_histogram_plot( 'latency', visualize_lib ) return plot - - @staticmethod - def create_period_histogram_plot( - target_objects: HistogramTypes - ) -> PlotBase: - """ - Get period histogram plot instance. - - Parameters - ---------- - target_objects : Collection[TimeSeriesTypes] - HistogramTypes = CallbackBase | Communication - Instances that are the sources of the plotting. - This also accepts multiple inputs by unpacking. - - Returns - ------- - PlotBase - - """ - visualize_lib = VisualizeLibFactory.create_instance() - plot = HistogramPlotFactory.create_instance( - parse_collection_or_unpack_for_hist(target_objects), # type: ignore - 'period', visualize_lib - ) - return plot diff --git a/src/caret_analyze/plot/visualize_lib/bokeh/bokeh.py b/src/caret_analyze/plot/visualize_lib/bokeh/bokeh.py index 17828a8fd..b26ec0fcd 100644 --- a/src/caret_analyze/plot/visualize_lib/bokeh/bokeh.py +++ b/src/caret_analyze/plot/visualize_lib/bokeh/bokeh.py @@ -21,7 +21,7 @@ from bokeh.plotting import Figure -from caret_analyze.record import Frequency, Latency, Period +from caret_analyze.record import Latency from numpy import histogram @@ -169,20 +169,20 @@ def timeseries( def histogram( self, - metrics: list[Frequency | Latency | Period], + metrics: list[Latency], callback_names: list[str], data_type: str ) -> Figure: - plot = Figure(title=data_type+' histogram', x_axis_label='x', y_axis_label='y') - latencies: list[list[int]] = [ + plot = Figure(title=data_type, x_axis_label='x', y_axis_label='y') + data_list: list[list[int]] = [ [_ for _ in m.to_records().get_column_series(data_type) if _ is not None] for m in metrics ] color_selector = ColorSelectorFactory.create_instance('unique') - max_value = max(max(latencies, key=lambda x: max(x))) - min_value = min(min(latencies, key=lambda x: min(x))) + max_value = max(max(data_list, key=lambda x: max(x))) + min_value = min(min(data_list, key=lambda x: min(x))) - for latency, callback_name in zip(latencies, callback_names): + for latency, callback_name in zip(data_list, callback_names): hist, bins = histogram(latency, 20, (min_value, max_value)) quad = plot.quad(top=hist, bottom=0, left=bins[:-1], right=bins[1:], diff --git a/src/caret_analyze/plot/visualize_lib/visualize_lib_interface.py b/src/caret_analyze/plot/visualize_lib/visualize_lib_interface.py index dc75c8be6..46ba49807 100644 --- a/src/caret_analyze/plot/visualize_lib/visualize_lib_interface.py +++ b/src/caret_analyze/plot/visualize_lib/visualize_lib_interface.py @@ -20,7 +20,7 @@ from bokeh.plotting import Figure from ..metrics_base import MetricsBase -from ...record import Frequency, Latency, Period +from ...record import Latency from ...runtime import CallbackBase, CallbackGroup, Communication, Path, Publisher, Subscription TimeSeriesTypes = CallbackBase | Communication | (Publisher | Subscription) @@ -90,7 +90,7 @@ def stacked_bar( def histogram( self, - metrics: list[Frequency | Latency | Period], + metrics: list[Latency], callback_names: list[str], data_type: str ) -> Figure: From 3e1129096404037fa8a1d1eb5a402399e5de3c76 Mon Sep 17 00:00:00 2001 From: emb4 Date: Thu, 31 Aug 2023 14:59:00 +0900 Subject: [PATCH 10/19] rename variable Signed-off-by: emb4 --- .../plot/histogram/histogram_plot.py | 6 ++---- src/caret_analyze/plot/plot_facade.py | 18 +++++++++--------- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/src/caret_analyze/plot/histogram/histogram_plot.py b/src/caret_analyze/plot/histogram/histogram_plot.py index 3f8897efc..d51e03fc3 100644 --- a/src/caret_analyze/plot/histogram/histogram_plot.py +++ b/src/caret_analyze/plot/histogram/histogram_plot.py @@ -23,10 +23,8 @@ from ..plot_base import PlotBase from ..visualize_lib import VisualizeLibInterface from ...exceptions import UnsupportedTypeError -from ...runtime import CallbackBase, Communication -HistogramTypes = CallbackBase | Communication -Hist_Types = list[Latency] +DataTypes = list[Latency] class HistogramPlot(PlotBase): @@ -34,7 +32,7 @@ class HistogramPlot(PlotBase): def __init__( self, - metrics: Hist_Types, + metrics: DataTypes, visualize_lib: VisualizeLibInterface, callback_names: list[str], data_type: str diff --git a/src/caret_analyze/plot/plot_facade.py b/src/caret_analyze/plot/plot_facade.py index 0807964c1..03280eca9 100644 --- a/src/caret_analyze/plot/plot_facade.py +++ b/src/caret_analyze/plot/plot_facade.py @@ -30,7 +30,7 @@ logger = getLogger(__name__) TimeSeriesTypes = CallbackBase | Communication | Publisher | Subscription -HistogramTypes = CallbackBase | Communication +HistTypes = CallbackBase | Communication CallbackSchedTypes = (Application | Executor | Path | Node | CallbackGroup | Collection[CallbackGroup]) @@ -65,8 +65,8 @@ def parse_collection_or_unpack( def parse_collection_or_unpack_for_hist( - target_arg: tuple[Collection[HistogramTypes]] | tuple[HistogramTypes, ...] -) -> list[HistogramTypes]: + target_arg: tuple[Collection[HistTypes]] | tuple[HistTypes, ...] +) -> list[HistTypes]: """ Parse target argument. @@ -75,15 +75,15 @@ def parse_collection_or_unpack_for_hist( Parameters ---------- - target_arg : tuple[Collection[HistogramTypes]] | tuple[HistogramTypes, ...] + target_arg : tuple[Collection[HistTypes]] | tuple[HistTypes, ...] Target objects. Returns ------- - list[HistogramTypes] + list[HistTypes] """ - parsed_target_objects: list[HistogramTypes] + parsed_target_objects: list[HistTypes] if isinstance(target_arg[0], Collection): assert len(target_arg) == 1 parsed_target_objects = list(target_arg[0]) @@ -306,15 +306,15 @@ def create_message_flow_plot( @staticmethod def create_latency_histogram_plot( - *target_objects: HistogramTypes + *target_objects: HistTypes ) -> PlotBase: """ Get latency histogram plot instance. Parameters ---------- - target_objects : Collection[HistogramTypes] - HistogramTypes = CallbackBase | Communication + target_objects : Collection[HistTypes] + HistTypes = CallbackBase | Communication Instances that are the sources of the plotting. This also accepts multiple inputs by unpacking. From 7c5ee50293717a114640a752ddce1748195fbf03 Mon Sep 17 00:00:00 2001 From: emb4 Date: Thu, 31 Aug 2023 16:05:10 +0900 Subject: [PATCH 11/19] The points raised in the review have been corrected. Signed-off-by: emb4 --- .../plot/histogram/histogram_plot.py | 12 ++-- .../plot/histogram/histogram_plot_factory.py | 35 ++++++++-- src/caret_analyze/plot/plot_facade.py | 70 ++++++++++++++++--- .../plot/visualize_lib/bokeh/bokeh.py | 5 +- .../visualize_lib/visualize_lib_interface.py | 5 +- 5 files changed, 104 insertions(+), 23 deletions(-) diff --git a/src/caret_analyze/plot/histogram/histogram_plot.py b/src/caret_analyze/plot/histogram/histogram_plot.py index d51e03fc3..d726456a5 100644 --- a/src/caret_analyze/plot/histogram/histogram_plot.py +++ b/src/caret_analyze/plot/histogram/histogram_plot.py @@ -16,7 +16,7 @@ from bokeh.plotting import Figure -from caret_analyze.record import Latency +from caret_analyze.record import Frequency, Latency, Period import pandas as pd @@ -24,7 +24,7 @@ from ..visualize_lib import VisualizeLibInterface from ...exceptions import UnsupportedTypeError -DataTypes = list[Latency] +HistTypes = Frequency | Latency | Period class HistogramPlot(PlotBase): @@ -32,7 +32,7 @@ class HistogramPlot(PlotBase): def __init__( self, - metrics: DataTypes, + metrics: HistTypes, visualize_lib: VisualizeLibInterface, callback_names: list[str], data_type: str @@ -100,7 +100,11 @@ def figure( # Validate self._validate_xaxis_type(xaxis_type) - return self._visualize_lib.histogram(self._metrics, self._callback_names, self._data_type) + return self._visualize_lib.histogram( + self._metrics, # type: ignore + self._callback_names, + self._data_type + ) def _validate_xaxis_type(self, xaxis_type: str) -> None: if xaxis_type not in ['system_time', 'sim_time', 'index']: diff --git a/src/caret_analyze/plot/histogram/histogram_plot_factory.py b/src/caret_analyze/plot/histogram/histogram_plot_factory.py index 8d1fe5c0a..2d791569f 100644 --- a/src/caret_analyze/plot/histogram/histogram_plot_factory.py +++ b/src/caret_analyze/plot/histogram/histogram_plot_factory.py @@ -16,7 +16,7 @@ from collections.abc import Sequence -from caret_analyze.record import Latency +from caret_analyze.record import Frequency, Latency, Period from .histogram_plot import HistogramPlot from ..visualize_lib import VisualizeLibInterface @@ -24,7 +24,8 @@ from ...exceptions import UnsupportedTypeError from ...runtime import CallbackBase, Communication -HistogramPlotTypes = CallbackBase | Communication +HistTypes = Frequency | Latency | Period +MetricsType = CallbackBase | Communication class HistogramPlotFactory: @@ -33,7 +34,7 @@ class HistogramPlotFactory: @staticmethod @type_check_decorator def create_instance( - target_objects: Sequence[HistogramPlotTypes], + target_objects: Sequence[MetricsType], metrics_name: str, visualize_lib: VisualizeLibInterface ) -> HistogramPlot: @@ -60,17 +61,39 @@ def create_instance( Argument metrics is not "latency". """ - metrics: list[Latency] = [] + metrics: list[HistTypes] = [] callback_names = [ obj.callback_name if isinstance(obj, CallbackBase) else obj.column_names[0].split('/')[-1] for obj in target_objects ] - if metrics_name == 'latency': + if metrics_name == 'frequency': + # Ignore the mypy type check because type_check_decorator is applied. + metrics = [Frequency(target_object.to_records()) for target_object in target_objects] + return HistogramPlot( + metrics, # type: ignore + visualize_lib, + callback_names, + metrics_name + ) + elif metrics_name == 'latency': # Ignore the mypy type check because type_check_decorator is applied. metrics = [Latency(target_object.to_records()) for target_object in target_objects] - return HistogramPlot(metrics, visualize_lib, callback_names, metrics_name) + return HistogramPlot( + metrics, # type: ignore + visualize_lib, + callback_names, + metrics_name + ) + elif metrics_name == 'period': + # Ignore the mypy type check because type_check_decorator is applied. + metrics = [Period(target_object.to_records()) for target_object in target_objects] + return HistogramPlot( + metrics, # type: ignore + visualize_lib, + callback_names, + metrics_name) else: raise UnsupportedTypeError( 'Unsupported metrics specified. ' diff --git a/src/caret_analyze/plot/plot_facade.py b/src/caret_analyze/plot/plot_facade.py index 03280eca9..cecd2b4b7 100644 --- a/src/caret_analyze/plot/plot_facade.py +++ b/src/caret_analyze/plot/plot_facade.py @@ -30,7 +30,7 @@ logger = getLogger(__name__) TimeSeriesTypes = CallbackBase | Communication | Publisher | Subscription -HistTypes = CallbackBase | Communication +MetricsType = CallbackBase | Communication CallbackSchedTypes = (Application | Executor | Path | Node | CallbackGroup | Collection[CallbackGroup]) @@ -65,8 +65,8 @@ def parse_collection_or_unpack( def parse_collection_or_unpack_for_hist( - target_arg: tuple[Collection[HistTypes]] | tuple[HistTypes, ...] -) -> list[HistTypes]: + target_arg: tuple[Collection[MetricsType]] | tuple[MetricsType, ...] +) -> list[MetricsType]: """ Parse target argument. @@ -75,15 +75,15 @@ def parse_collection_or_unpack_for_hist( Parameters ---------- - target_arg : tuple[Collection[HistTypes]] | tuple[HistTypes, ...] + target_arg : tuple[Collection[MetricsType]] | tuple[MetricsType, ...] Target objects. Returns ------- - list[HistTypes] + list[MetricsType] """ - parsed_target_objects: list[HistTypes] + parsed_target_objects: list[MetricsType] if isinstance(target_arg[0], Collection): assert len(target_arg) == 1 parsed_target_objects = list(target_arg[0]) @@ -304,17 +304,43 @@ def create_message_flow_plot( ) return plot + @staticmethod + def create_frequency_histogram_plot( + *target_objects: MetricsType + ) -> PlotBase: + """ + Get frequency histogram plot instance. + + Parameters + ---------- + target_objects : Collection[MetricsType] + MetricsType = CallbackBase | Communication + Instances that are the sources of the plotting. + This also accepts multiple inputs by unpacking. + + Returns + ------- + PlotBase + + """ + visualize_lib = VisualizeLibFactory.create_instance() + plot = HistogramPlotFactory.create_instance( + parse_collection_or_unpack_for_hist(target_objects), # type: ignore + 'frequency', visualize_lib + ) + return plot + @staticmethod def create_latency_histogram_plot( - *target_objects: HistTypes + *target_objects: MetricsType ) -> PlotBase: """ Get latency histogram plot instance. Parameters ---------- - target_objects : Collection[HistTypes] - HistTypes = CallbackBase | Communication + target_objects : Collection[MetricsType] + MetricsType = CallbackBase | Communication Instances that are the sources of the plotting. This also accepts multiple inputs by unpacking. @@ -329,3 +355,29 @@ def create_latency_histogram_plot( 'latency', visualize_lib ) return plot + + @staticmethod + def create_period_histogram_plot( + *target_objects: MetricsType + ) -> PlotBase: + """ + Get period histogram plot instance. + + Parameters + ---------- + target_objects : Collection[MetricsType] + MetricsType = CallbackBase | Communication + Instances that are the sources of the plotting. + This also accepts multiple inputs by unpacking. + + Returns + ------- + PlotBase + + """ + visualize_lib = VisualizeLibFactory.create_instance() + plot = HistogramPlotFactory.create_instance( + parse_collection_or_unpack_for_hist(target_objects), # type: ignore + 'period', visualize_lib + ) + return plot diff --git a/src/caret_analyze/plot/visualize_lib/bokeh/bokeh.py b/src/caret_analyze/plot/visualize_lib/bokeh/bokeh.py index b26ec0fcd..4779be8bd 100644 --- a/src/caret_analyze/plot/visualize_lib/bokeh/bokeh.py +++ b/src/caret_analyze/plot/visualize_lib/bokeh/bokeh.py @@ -21,7 +21,7 @@ from bokeh.plotting import Figure -from caret_analyze.record import Latency +from caret_analyze.record import Frequency, Latency, Period from numpy import histogram @@ -36,6 +36,7 @@ from ....runtime import CallbackBase, CallbackGroup, Communication, Path, Publisher, Subscription TimeSeriesTypes = CallbackBase | Communication | (Publisher | Subscription) +HistTypes = Frequency | Latency | Period logger = getLogger(__name__) @@ -169,7 +170,7 @@ def timeseries( def histogram( self, - metrics: list[Latency], + metrics: list[HistTypes], callback_names: list[str], data_type: str ) -> Figure: diff --git a/src/caret_analyze/plot/visualize_lib/visualize_lib_interface.py b/src/caret_analyze/plot/visualize_lib/visualize_lib_interface.py index 46ba49807..23439d96b 100644 --- a/src/caret_analyze/plot/visualize_lib/visualize_lib_interface.py +++ b/src/caret_analyze/plot/visualize_lib/visualize_lib_interface.py @@ -20,10 +20,11 @@ from bokeh.plotting import Figure from ..metrics_base import MetricsBase -from ...record import Latency +from ...record import Frequency, Latency, Period from ...runtime import CallbackBase, CallbackGroup, Communication, Path, Publisher, Subscription TimeSeriesTypes = CallbackBase | Communication | (Publisher | Subscription) +HistTypes = Frequency | Latency | Period class VisualizeLibInterface(metaclass=ABCMeta): @@ -90,7 +91,7 @@ def stacked_bar( def histogram( self, - metrics: list[Latency], + metrics: list[HistTypes], callback_names: list[str], data_type: str ) -> Figure: From 73a3549622935a3aaae6a0fb89aebbd72dd9e825 Mon Sep 17 00:00:00 2001 From: emb4 Date: Fri, 1 Sep 2023 10:24:51 +0900 Subject: [PATCH 12/19] The points raised in the review have been corrected. Signed-off-by: emb4 --- .../plot/histogram/histogram_plot.py | 6 ++-- .../plot/histogram/histogram_plot_factory.py | 12 ++++---- src/caret_analyze/plot/plot_facade.py | 30 +++++++++---------- .../plot/visualize_lib/bokeh/bokeh.py | 4 +-- .../visualize_lib/visualize_lib_interface.py | 4 +-- 5 files changed, 28 insertions(+), 28 deletions(-) diff --git a/src/caret_analyze/plot/histogram/histogram_plot.py b/src/caret_analyze/plot/histogram/histogram_plot.py index d726456a5..dda155418 100644 --- a/src/caret_analyze/plot/histogram/histogram_plot.py +++ b/src/caret_analyze/plot/histogram/histogram_plot.py @@ -24,7 +24,7 @@ from ..visualize_lib import VisualizeLibInterface from ...exceptions import UnsupportedTypeError -HistTypes = Frequency | Latency | Period +MetricsTypes = Frequency | Latency | Period class HistogramPlot(PlotBase): @@ -32,7 +32,7 @@ class HistogramPlot(PlotBase): def __init__( self, - metrics: HistTypes, + metrics: list[MetricsTypes], visualize_lib: VisualizeLibInterface, callback_names: list[str], data_type: str @@ -101,7 +101,7 @@ def figure( self._validate_xaxis_type(xaxis_type) return self._visualize_lib.histogram( - self._metrics, # type: ignore + self._metrics, self._callback_names, self._data_type ) diff --git a/src/caret_analyze/plot/histogram/histogram_plot_factory.py b/src/caret_analyze/plot/histogram/histogram_plot_factory.py index 2d791569f..55aa3959a 100644 --- a/src/caret_analyze/plot/histogram/histogram_plot_factory.py +++ b/src/caret_analyze/plot/histogram/histogram_plot_factory.py @@ -24,8 +24,8 @@ from ...exceptions import UnsupportedTypeError from ...runtime import CallbackBase, Communication -HistTypes = Frequency | Latency | Period -MetricsType = CallbackBase | Communication +MetricsType = Frequency | Latency | Period +HistTypes = CallbackBase | Communication class HistogramPlotFactory: @@ -34,7 +34,7 @@ class HistogramPlotFactory: @staticmethod @type_check_decorator def create_instance( - target_objects: Sequence[MetricsType], + target_objects: Sequence[HistTypes], metrics_name: str, visualize_lib: VisualizeLibInterface ) -> HistogramPlot: @@ -43,8 +43,8 @@ def create_instance( Parameters ---------- - target_objects : Sequence[HistogramPlotTypes] - HistogramPlotTypes = CallbackBase | Communication + target_objects : Sequence[HistTypes] + HistTypes = CallbackBase | Communication metrics_name : str Metrics for histogramplot data. supported metrics: [frequency/latency/period] @@ -61,7 +61,7 @@ def create_instance( Argument metrics is not "latency". """ - metrics: list[HistTypes] = [] + metrics: list[MetricsType] = [] callback_names = [ obj.callback_name if isinstance(obj, CallbackBase) else obj.column_names[0].split('/')[-1] diff --git a/src/caret_analyze/plot/plot_facade.py b/src/caret_analyze/plot/plot_facade.py index cecd2b4b7..9664a4e16 100644 --- a/src/caret_analyze/plot/plot_facade.py +++ b/src/caret_analyze/plot/plot_facade.py @@ -30,7 +30,7 @@ logger = getLogger(__name__) TimeSeriesTypes = CallbackBase | Communication | Publisher | Subscription -MetricsType = CallbackBase | Communication +HistTypes = CallbackBase | Communication CallbackSchedTypes = (Application | Executor | Path | Node | CallbackGroup | Collection[CallbackGroup]) @@ -65,8 +65,8 @@ def parse_collection_or_unpack( def parse_collection_or_unpack_for_hist( - target_arg: tuple[Collection[MetricsType]] | tuple[MetricsType, ...] -) -> list[MetricsType]: + target_arg: tuple[Collection[HistTypes]] | tuple[HistTypes, ...] +) -> list[HistTypes]: """ Parse target argument. @@ -75,15 +75,15 @@ def parse_collection_or_unpack_for_hist( Parameters ---------- - target_arg : tuple[Collection[MetricsType]] | tuple[MetricsType, ...] + target_arg : tuple[Collection[HistTypes]] | tuple[HistTypes, ...] Target objects. Returns ------- - list[MetricsType] + list[HistTypes] """ - parsed_target_objects: list[MetricsType] + parsed_target_objects: list[HistTypes] if isinstance(target_arg[0], Collection): assert len(target_arg) == 1 parsed_target_objects = list(target_arg[0]) @@ -306,15 +306,15 @@ def create_message_flow_plot( @staticmethod def create_frequency_histogram_plot( - *target_objects: MetricsType + *target_objects: HistTypes ) -> PlotBase: """ Get frequency histogram plot instance. Parameters ---------- - target_objects : Collection[MetricsType] - MetricsType = CallbackBase | Communication + target_objects : Collection[HistTypes] + HistTypes = CallbackBase | Communication Instances that are the sources of the plotting. This also accepts multiple inputs by unpacking. @@ -332,15 +332,15 @@ def create_frequency_histogram_plot( @staticmethod def create_latency_histogram_plot( - *target_objects: MetricsType + *target_objects: HistTypes ) -> PlotBase: """ Get latency histogram plot instance. Parameters ---------- - target_objects : Collection[MetricsType] - MetricsType = CallbackBase | Communication + target_objects : Collection[HistTypes] + HistTypes = CallbackBase | Communication Instances that are the sources of the plotting. This also accepts multiple inputs by unpacking. @@ -358,15 +358,15 @@ def create_latency_histogram_plot( @staticmethod def create_period_histogram_plot( - *target_objects: MetricsType + *target_objects: HistTypes ) -> PlotBase: """ Get period histogram plot instance. Parameters ---------- - target_objects : Collection[MetricsType] - MetricsType = CallbackBase | Communication + target_objects : Collection[HistTypes] + HistTypes = CallbackBase | Communication Instances that are the sources of the plotting. This also accepts multiple inputs by unpacking. diff --git a/src/caret_analyze/plot/visualize_lib/bokeh/bokeh.py b/src/caret_analyze/plot/visualize_lib/bokeh/bokeh.py index 4779be8bd..f0d7c2ef6 100644 --- a/src/caret_analyze/plot/visualize_lib/bokeh/bokeh.py +++ b/src/caret_analyze/plot/visualize_lib/bokeh/bokeh.py @@ -36,7 +36,7 @@ from ....runtime import CallbackBase, CallbackGroup, Communication, Path, Publisher, Subscription TimeSeriesTypes = CallbackBase | Communication | (Publisher | Subscription) -HistTypes = Frequency | Latency | Period +MetricsTypes = Frequency | Latency | Period logger = getLogger(__name__) @@ -170,7 +170,7 @@ def timeseries( def histogram( self, - metrics: list[HistTypes], + metrics: list[MetricsTypes], callback_names: list[str], data_type: str ) -> Figure: diff --git a/src/caret_analyze/plot/visualize_lib/visualize_lib_interface.py b/src/caret_analyze/plot/visualize_lib/visualize_lib_interface.py index 23439d96b..e0306aad3 100644 --- a/src/caret_analyze/plot/visualize_lib/visualize_lib_interface.py +++ b/src/caret_analyze/plot/visualize_lib/visualize_lib_interface.py @@ -24,7 +24,7 @@ from ...runtime import CallbackBase, CallbackGroup, Communication, Path, Publisher, Subscription TimeSeriesTypes = CallbackBase | Communication | (Publisher | Subscription) -HistTypes = Frequency | Latency | Period +MetricsTypes = Frequency | Latency | Period class VisualizeLibInterface(metaclass=ABCMeta): @@ -91,7 +91,7 @@ def stacked_bar( def histogram( self, - metrics: list[HistTypes], + metrics: list[MetricsTypes], callback_names: list[str], data_type: str ) -> Figure: From 2a6c4ebb98835763cb4e052fea7ddf01df74532b Mon Sep 17 00:00:00 2001 From: emb4 Date: Fri, 1 Sep 2023 14:47:08 +0900 Subject: [PATCH 13/19] The points raised in the review have been corrected. Signed-off-by: emb4 --- src/caret_analyze/plot/histogram/histogram_plot_factory.py | 4 ++-- src/caret_analyze/plot/visualize_lib/bokeh/bokeh.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/caret_analyze/plot/histogram/histogram_plot_factory.py b/src/caret_analyze/plot/histogram/histogram_plot_factory.py index 55aa3959a..5c73c67ab 100644 --- a/src/caret_analyze/plot/histogram/histogram_plot_factory.py +++ b/src/caret_analyze/plot/histogram/histogram_plot_factory.py @@ -46,7 +46,7 @@ def create_instance( target_objects : Sequence[HistTypes] HistTypes = CallbackBase | Communication metrics_name : str - Metrics for histogramplot data. + Metrics for HistogramPlot data. supported metrics: [frequency/latency/period] visualize_lib : VisualizeLibInterface Instance of VisualizeLibInterface used for visualization. @@ -58,7 +58,7 @@ def create_instance( Raises ------ UnsupportedTypeError - Argument metrics is not "latency". + Argument metrics is not "frequency", "latency", or "period". """ metrics: list[MetricsType] = [] diff --git a/src/caret_analyze/plot/visualize_lib/bokeh/bokeh.py b/src/caret_analyze/plot/visualize_lib/bokeh/bokeh.py index f0d7c2ef6..967ebe8d9 100644 --- a/src/caret_analyze/plot/visualize_lib/bokeh/bokeh.py +++ b/src/caret_analyze/plot/visualize_lib/bokeh/bokeh.py @@ -183,8 +183,8 @@ def histogram( max_value = max(max(data_list, key=lambda x: max(x))) min_value = min(min(data_list, key=lambda x: min(x))) - for latency, callback_name in zip(data_list, callback_names): - hist, bins = histogram(latency, 20, (min_value, max_value)) + for hist_type, callback_name in zip(data_list, callback_names): + hist, bins = histogram(hist_type, 20, (min_value, max_value)) quad = plot.quad(top=hist, bottom=0, left=bins[:-1], right=bins[1:], line_color='white', alpha=0.5, legend_label=callback_name, From 64027699c2b446beeaa372f4972d1f7d20cbf013 Mon Sep 17 00:00:00 2001 From: emb4 Date: Fri, 1 Sep 2023 16:29:07 +0900 Subject: [PATCH 14/19] The points raised in the review have been corrected. Signed-off-by: emb4 --- .../plot/histogram/histogram_plot_factory.py | 12 +++++------- src/caret_analyze/plot/plot_facade.py | 6 +++--- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/src/caret_analyze/plot/histogram/histogram_plot_factory.py b/src/caret_analyze/plot/histogram/histogram_plot_factory.py index 5c73c67ab..295cc7a09 100644 --- a/src/caret_analyze/plot/histogram/histogram_plot_factory.py +++ b/src/caret_analyze/plot/histogram/histogram_plot_factory.py @@ -69,31 +69,29 @@ def create_instance( ] if metrics_name == 'frequency': - # Ignore the mypy type check because type_check_decorator is applied. metrics = [Frequency(target_object.to_records()) for target_object in target_objects] return HistogramPlot( - metrics, # type: ignore + metrics, visualize_lib, callback_names, metrics_name ) elif metrics_name == 'latency': - # Ignore the mypy type check because type_check_decorator is applied. metrics = [Latency(target_object.to_records()) for target_object in target_objects] return HistogramPlot( - metrics, # type: ignore + metrics, visualize_lib, callback_names, metrics_name ) elif metrics_name == 'period': - # Ignore the mypy type check because type_check_decorator is applied. metrics = [Period(target_object.to_records()) for target_object in target_objects] return HistogramPlot( - metrics, # type: ignore + metrics, visualize_lib, callback_names, - metrics_name) + metrics_name + ) else: raise UnsupportedTypeError( 'Unsupported metrics specified. ' diff --git a/src/caret_analyze/plot/plot_facade.py b/src/caret_analyze/plot/plot_facade.py index 9664a4e16..9addeb75d 100644 --- a/src/caret_analyze/plot/plot_facade.py +++ b/src/caret_analyze/plot/plot_facade.py @@ -325,7 +325,7 @@ def create_frequency_histogram_plot( """ visualize_lib = VisualizeLibFactory.create_instance() plot = HistogramPlotFactory.create_instance( - parse_collection_or_unpack_for_hist(target_objects), # type: ignore + parse_collection_or_unpack_for_hist(target_objects), 'frequency', visualize_lib ) return plot @@ -351,7 +351,7 @@ def create_latency_histogram_plot( """ visualize_lib = VisualizeLibFactory.create_instance() plot = HistogramPlotFactory.create_instance( - parse_collection_or_unpack_for_hist(target_objects), # type: ignore + parse_collection_or_unpack_for_hist(target_objects), 'latency', visualize_lib ) return plot @@ -377,7 +377,7 @@ def create_period_histogram_plot( """ visualize_lib = VisualizeLibFactory.create_instance() plot = HistogramPlotFactory.create_instance( - parse_collection_or_unpack_for_hist(target_objects), # type: ignore + parse_collection_or_unpack_for_hist(target_objects), 'period', visualize_lib ) return plot From 15f28f14ebd53f323a4c37430c26e69cd44611e7 Mon Sep 17 00:00:00 2001 From: emb4 Date: Thu, 7 Sep 2023 16:49:27 +0900 Subject: [PATCH 15/19] The graph legend has been corrected. Signed-off-by: emb4 --- .../plot/histogram/histogram_plot.py | 10 ++++-- .../plot/histogram/histogram_plot_factory.py | 28 +++++++-------- .../plot/visualize_lib/bokeh/bokeh.py | 35 +++++++++++++------ .../visualize_lib/visualize_lib_interface.py | 3 +- 4 files changed, 46 insertions(+), 30 deletions(-) diff --git a/src/caret_analyze/plot/histogram/histogram_plot.py b/src/caret_analyze/plot/histogram/histogram_plot.py index dda155418..b22d1d72b 100644 --- a/src/caret_analyze/plot/histogram/histogram_plot.py +++ b/src/caret_analyze/plot/histogram/histogram_plot.py @@ -14,6 +14,8 @@ from __future__ import annotations +from collections.abc import Sequence + from bokeh.plotting import Figure from caret_analyze.record import Frequency, Latency, Period @@ -23,8 +25,10 @@ from ..plot_base import PlotBase from ..visualize_lib import VisualizeLibInterface from ...exceptions import UnsupportedTypeError +from ...runtime import CallbackBase, Communication MetricsTypes = Frequency | Latency | Period +HistTypes = CallbackBase | Communication class HistogramPlot(PlotBase): @@ -34,12 +38,12 @@ def __init__( self, metrics: list[MetricsTypes], visualize_lib: VisualizeLibInterface, - callback_names: list[str], + target_objects: Sequence[HistTypes], data_type: str ) -> None: self._metrics = metrics self._visualize_lib = visualize_lib - self._callback_names = callback_names + self._target_objects = target_objects self._data_type = data_type def to_dataframe( @@ -102,7 +106,7 @@ def figure( return self._visualize_lib.histogram( self._metrics, - self._callback_names, + self._target_objects, self._data_type ) diff --git a/src/caret_analyze/plot/histogram/histogram_plot_factory.py b/src/caret_analyze/plot/histogram/histogram_plot_factory.py index 295cc7a09..ef254b1bd 100644 --- a/src/caret_analyze/plot/histogram/histogram_plot_factory.py +++ b/src/caret_analyze/plot/histogram/histogram_plot_factory.py @@ -61,35 +61,31 @@ def create_instance( Argument metrics is not "frequency", "latency", or "period". """ - metrics: list[MetricsType] = [] - callback_names = [ - obj.callback_name if isinstance(obj, CallbackBase) - else obj.column_names[0].split('/')[-1] - for obj in target_objects - ] - if metrics_name == 'frequency': - metrics = [Frequency(target_object.to_records()) for target_object in target_objects] + metrics_frequency: list[MetricsType] =\ + [Frequency(target_object.to_records()) for target_object in target_objects] return HistogramPlot( - metrics, + metrics_frequency, visualize_lib, - callback_names, + target_objects, metrics_name ) elif metrics_name == 'latency': - metrics = [Latency(target_object.to_records()) for target_object in target_objects] + metrics_latency: list[MetricsType] =\ + [Latency(target_object.to_records()) for target_object in target_objects] return HistogramPlot( - metrics, + metrics_latency, visualize_lib, - callback_names, + target_objects, metrics_name ) elif metrics_name == 'period': - metrics = [Period(target_object.to_records()) for target_object in target_objects] + metrics_period: list[MetricsType] =\ + [Period(target_object.to_records()) for target_object in target_objects] return HistogramPlot( - metrics, + metrics_period, visualize_lib, - callback_names, + target_objects, metrics_name ) else: diff --git a/src/caret_analyze/plot/visualize_lib/bokeh/bokeh.py b/src/caret_analyze/plot/visualize_lib/bokeh/bokeh.py index 967ebe8d9..f4ee0358e 100644 --- a/src/caret_analyze/plot/visualize_lib/bokeh/bokeh.py +++ b/src/caret_analyze/plot/visualize_lib/bokeh/bokeh.py @@ -30,13 +30,14 @@ from .response_time_hist import BokehResponseTimeHist from .stacked_bar import BokehStackedBar from .timeseries import BokehTimeSeries -from .util import ColorSelectorFactory +from .util import ColorSelectorFactory, LegendManager from ..visualize_lib_interface import VisualizeLibInterface from ...metrics_base import MetricsBase from ....runtime import CallbackBase, CallbackGroup, Communication, Path, Publisher, Subscription TimeSeriesTypes = CallbackBase | Communication | (Publisher | Subscription) MetricsTypes = Frequency | Latency | Period +HistTypes = CallbackBase | Communication logger = getLogger(__name__) @@ -171,27 +172,41 @@ def timeseries( def histogram( self, metrics: list[MetricsTypes], - callback_names: list[str], + target_objects: Sequence[HistTypes], data_type: str ) -> Figure: - plot = Figure(title=data_type, x_axis_label='x', y_axis_label='y') + legend_manager = LegendManager() + if data_type == 'frequency': + x_label = data_type + ' [Hz]' + elif data_type in ['period', 'latency']: + x_label = data_type + ' [ms]' + else: + raise NotImplementedError() + plot = Figure( + title=data_type, x_axis_label=x_label, y_axis_label='Probability', plot_width=800 + ) data_list: list[list[int]] = [ [_ for _ in m.to_records().get_column_series(data_type) if _ is not None] for m in metrics ] color_selector = ColorSelectorFactory.create_instance('unique') + if data_type in ['period', 'latency']: + data_list = [[_ *10**(-6) for _ in data] for data in data_list] max_value = max(max(data_list, key=lambda x: max(x))) min_value = min(min(data_list, key=lambda x: min(x))) - - for hist_type, callback_name in zip(data_list, callback_names): + for hist_type, target_object in zip(data_list, target_objects): hist, bins = histogram(hist_type, 20, (min_value, max_value)) quad = plot.quad(top=hist, bottom=0, left=bins[:-1], right=bins[1:], - line_color='white', alpha=0.5, legend_label=callback_name, + line_color='white', alpha=0.5, color=color_selector.get_color()) - hover = HoverTool(tooltips=[('x', '@left'), ('y', '@top')], renderers=[quad]) + legend_manager.add_legend(target_object, quad) + hover = HoverTool( + tooltips=[(x_label, '@left'), ('Probability', '@top')], renderers=[quad] + ) plot.add_tools(hover) - plot.legend.title = 'Legend' - plot.legend.location = 'top_right' - plot.legend.label_text_font_size = '12pt' + + legends = legend_manager.create_legends(20, True, location='top_right') + for legend in legends: + plot.add_layout(legend, 'right') return plot diff --git a/src/caret_analyze/plot/visualize_lib/visualize_lib_interface.py b/src/caret_analyze/plot/visualize_lib/visualize_lib_interface.py index e0306aad3..f041db8dc 100644 --- a/src/caret_analyze/plot/visualize_lib/visualize_lib_interface.py +++ b/src/caret_analyze/plot/visualize_lib/visualize_lib_interface.py @@ -25,6 +25,7 @@ TimeSeriesTypes = CallbackBase | Communication | (Publisher | Subscription) MetricsTypes = Frequency | Latency | Period +HistTypes = CallbackBase | Communication class VisualizeLibInterface(metaclass=ABCMeta): @@ -92,7 +93,7 @@ def stacked_bar( def histogram( self, metrics: list[MetricsTypes], - callback_names: list[str], + target_objects: Sequence[HistTypes], data_type: str ) -> Figure: raise NotImplementedError() From 7b09242a42de64196829dfa942ddbd99accf2a6e Mon Sep 17 00:00:00 2001 From: emb4 Date: Fri, 8 Sep 2023 11:25:30 +0900 Subject: [PATCH 16/19] The vertical axis has been changed to a probability notation. Signed-off-by: emb4 --- src/caret_analyze/plot/visualize_lib/bokeh/bokeh.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/caret_analyze/plot/visualize_lib/bokeh/bokeh.py b/src/caret_analyze/plot/visualize_lib/bokeh/bokeh.py index f4ee0358e..09582193c 100644 --- a/src/caret_analyze/plot/visualize_lib/bokeh/bokeh.py +++ b/src/caret_analyze/plot/visualize_lib/bokeh/bokeh.py @@ -195,7 +195,7 @@ def histogram( max_value = max(max(data_list, key=lambda x: max(x))) min_value = min(min(data_list, key=lambda x: min(x))) for hist_type, target_object in zip(data_list, target_objects): - hist, bins = histogram(hist_type, 20, (min_value, max_value)) + hist, bins = histogram(hist_type, 20, (min_value, max_value), density=True) quad = plot.quad(top=hist, bottom=0, left=bins[:-1], right=bins[1:], line_color='white', alpha=0.5, From 94b87f71eb2121481ca1e2fb0e358d2433292542 Mon Sep 17 00:00:00 2001 From: emb4 Date: Thu, 14 Sep 2023 16:06:08 +0900 Subject: [PATCH 17/19] autoware is now supported. Signed-off-by: emb4 --- src/caret_analyze/plot/visualize_lib/bokeh/bokeh.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/caret_analyze/plot/visualize_lib/bokeh/bokeh.py b/src/caret_analyze/plot/visualize_lib/bokeh/bokeh.py index 09582193c..59008d9d2 100644 --- a/src/caret_analyze/plot/visualize_lib/bokeh/bokeh.py +++ b/src/caret_analyze/plot/visualize_lib/bokeh/bokeh.py @@ -192,8 +192,14 @@ def histogram( color_selector = ColorSelectorFactory.create_instance('unique') if data_type in ['period', 'latency']: data_list = [[_ *10**(-6) for _ in data] for data in data_list] - max_value = max(max(data_list, key=lambda x: max(x))) - min_value = min(min(data_list, key=lambda x: min(x))) + # max_value = max(max(data_list, key=lambda x: max(x))) + max_value = max( + max([max_len for max_len in data_list if len(max_len)], key=lambda x: max(x)) + ) + # min_value = min(min(data_list, key=lambda x: min(x))) + min_value = min( + min([min_len for min_len in data_list if len(min_len)], key=lambda x: min(x)) + ) for hist_type, target_object in zip(data_list, target_objects): hist, bins = histogram(hist_type, 20, (min_value, max_value), density=True) quad = plot.quad(top=hist, bottom=0, @@ -206,7 +212,7 @@ def histogram( ) plot.add_tools(hover) - legends = legend_manager.create_legends(20, True, location='top_right') + legends = legend_manager.create_legends(20, False, location='top_right') for legend in legends: plot.add_layout(legend, 'right') return plot From f874ae76c856f735835d70b504f59e5f01a0d5aa Mon Sep 17 00:00:00 2001 From: emb4 Date: Fri, 15 Sep 2023 11:46:46 +0900 Subject: [PATCH 18/19] Removed unnecessary comment-outs. Signed-off-by: emb4 --- src/caret_analyze/plot/visualize_lib/bokeh/bokeh.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/caret_analyze/plot/visualize_lib/bokeh/bokeh.py b/src/caret_analyze/plot/visualize_lib/bokeh/bokeh.py index 59008d9d2..055843c5e 100644 --- a/src/caret_analyze/plot/visualize_lib/bokeh/bokeh.py +++ b/src/caret_analyze/plot/visualize_lib/bokeh/bokeh.py @@ -17,7 +17,7 @@ from collections.abc import Sequence from logging import getLogger -from bokeh.models import HoverTool +from bokeh.models import GlyphRenderer, HoverTool, Legend from bokeh.plotting import Figure @@ -46,7 +46,7 @@ class Bokeh(VisualizeLibInterface): """Class that visualizes data using Bokeh library.""" def __init__(self) -> None: - pass + self._legend_items: list[tuple[str, list[GlyphRenderer]]] = [] def response_time_hist( self, @@ -192,11 +192,9 @@ def histogram( color_selector = ColorSelectorFactory.create_instance('unique') if data_type in ['period', 'latency']: data_list = [[_ *10**(-6) for _ in data] for data in data_list] - # max_value = max(max(data_list, key=lambda x: max(x))) max_value = max( max([max_len for max_len in data_list if len(max_len)], key=lambda x: max(x)) ) - # min_value = min(min(data_list, key=lambda x: min(x))) min_value = min( min([min_len for min_len in data_list if len(min_len)], key=lambda x: min(x)) ) From bba9f86b7b6e980abb1cd549fd68e723748438d8 Mon Sep 17 00:00:00 2001 From: emb4 Date: Fri, 15 Sep 2023 15:19:04 +0900 Subject: [PATCH 19/19] The pytest error has been resolved. Signed-off-by: emb4 --- src/caret_analyze/plot/visualize_lib/bokeh/bokeh.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/caret_analyze/plot/visualize_lib/bokeh/bokeh.py b/src/caret_analyze/plot/visualize_lib/bokeh/bokeh.py index e6988da54..29b00487f 100644 --- a/src/caret_analyze/plot/visualize_lib/bokeh/bokeh.py +++ b/src/caret_analyze/plot/visualize_lib/bokeh/bokeh.py @@ -17,7 +17,7 @@ from collections.abc import Sequence from logging import getLogger -from bokeh.models import GlyphRenderer, HoverTool, Legend +from bokeh.models import GlyphRenderer, HoverTool from bokeh.plotting import Figure