diff --git a/src/caret_analyze/plot/visualize_lib/bokeh/bokeh.py b/src/caret_analyze/plot/visualize_lib/bokeh/bokeh.py index d90876319..f303e10b7 100644 --- a/src/caret_analyze/plot/visualize_lib/bokeh/bokeh.py +++ b/src/caret_analyze/plot/visualize_lib/bokeh/bokeh.py @@ -24,7 +24,8 @@ from caret_analyze.record import Frequency, Latency, Period, ResponseTime -from numpy import empty, histogram +import numpy as np +from numpy import histogram from .callback_scheduling import BokehCallbackSched from .message_flow import BokehMessageFlow @@ -256,8 +257,6 @@ def histogram( if not isinstance(m, ResponseTime) ] - color_selector = ColorSelectorFactory.create_instance('unique') - if data_type in ['period', 'latency', 'response_time']: data_list = [[_ *10**(-6) for _ in data] for data in data_list] @@ -269,23 +268,41 @@ def histogram( else: data_range = None - for hist_type, target_object in zip(data_list, target_objects): - if len(hist_type) != 0: - hist, bins = histogram(hist_type, 20, data_range, density=False) - else: - hist = empty(0) - bins = empty(0) - quad = plot.quad(top=hist, bottom=0, - left=bins[:-1], right=bins[1:], - line_color='white', alpha=0.5, - color=color_selector.get_color()) - legend_manager.add_legend(target_object, quad) - hover = HoverTool( - tooltips=[(x_label, '@left'), ('The number of samples', '@top')], renderers=[quad] - ) - plot.add_tools(hover) + hists = [] + + for hist_type in data_list: + hist, bins = histogram(hist_type, 20, data_range, density=False) + hists.append(hist) + + hists_t = np.array(hists).T + + color_selector = ColorSelectorFactory.create_instance('unique') + colors = [color_selector.get_color() for _ in target_objects] + + quad_dicts: dict = {t: [] for t in target_objects} + + for i, h in enumerate(hists_t): + data = list(zip(h, colors, target_objects)) + data.sort(key=lambda x: x[0], reverse=True) + for top, color, target_object in data: + if top == 0: + continue + quad = plot.quad( + top=top, bottom=0, left=bins[i], right=bins[i+1], + color=color, alpha=1, line_color='white' + ) + hover = HoverTool( + tooltips=[(x_label, f'{bins[i]}'), ('The number of samples', f'{top}')], + renderers=[quad] + ) + plot.add_tools(hover) + quad_dicts[target_object] = quad_dicts[target_object] + [quad] + + for target_object_key, quad_value in quad_dicts.items(): + legend_manager.add_legend(target_object_key, quad_value) legends = legend_manager.create_legends(20, False, location='top_right', separate=20) for legend in legends: plot.add_layout(legend, 'right') + plot.legend.click_policy = 'hide' return plot diff --git a/src/caret_analyze/plot/visualize_lib/bokeh/util/legend.py b/src/caret_analyze/plot/visualize_lib/bokeh/util/legend.py index b4f603300..d8e508665 100644 --- a/src/caret_analyze/plot/visualize_lib/bokeh/util/legend.py +++ b/src/caret_analyze/plot/visualize_lib/bokeh/util/legend.py @@ -39,7 +39,7 @@ def __init__(self) -> None: def add_legend( self, target_object: Any, - renderer: GlyphRenderer, + renderer: GlyphRenderer | list[GlyphRenderer], legend_word: str | None = None, ) -> None: """ @@ -58,7 +58,9 @@ def add_legend( """ label = self.get_label(target_object, legend_word) - self._legend_items.append((label, [renderer])) + if not isinstance(renderer, list): + renderer = [renderer] + self._legend_items.append((label, renderer)) self._legend[target_object] = label def create_legends(