環境
- Python 3.12.1
- bokeh 3.4.2
やりたいこと
bokehを使って、10本以上の折れ線を描画しています。
import bokeh
import numpy
from bokeh.plotting import figure, output_file, save
import bokeh.palettes
x_data = numpy.arange(-20, 20, 0.1)
palette = bokeh.palettes.Category10[10]
fig = figure(x_axis_label="x", y_axis_label="y", width=600, height=400)
for i in range(10):
legend_label = f"y=sin(x + {i})"
fig.line(
x_data,
numpy.sin(x_data + i),
color=palette[i],
legend_label=legend_label,
)
fig.legend.click_policy = "hide"
# 凡例をグラフの外に配置する
legend = fig.legend[0]
fig.add_layout(legend, "left")
output_file("graph1.html")
save(fig)
折れ線が重なり合っているので、たとえば y=sin(x + 5)
の折れ線がどれなのか、ぱっと見分かりません。
なので、特定の折れ線を目立つように表示したいです。
やったこと
MultiChoice widgetを使って、折れ線を選択できるようにしました。
選択された折れ線は、線を太くして目立たせました。
import bokeh
import numpy
from bokeh.plotting import figure, output_file, save
import bokeh.palettes
from bokeh.models import CustomJS
from bokeh.models.renderers.glyph_renderer import GlyphRenderer
from bokeh.models.widgets.inputs import MultiChoice
from typing import Final
DEFAULT_LINE_WIDTH: Final[int] = 1
def create_multi_choice_widget(line_glyphs: dict[str, GlyphRenderer]) -> MultiChoice:
args = {"lineGlyphs": line_glyphs}
SELECTED_LINE_WIDTH: Final[int] = 4
code = f"""
const selectedLegendLabel = this.value;
for (let legendLabel in lineGlyphs) {{
if (selectedLegendLabel.includes(legendLabel)) {{
lineGlyphs[legendLabel].glyph.line_width = {SELECTED_LINE_WIDTH};
}} else {{
lineGlyphs[legendLabel].glyph.line_width = {DEFAULT_LINE_WIDTH};
}}
}}
"""
options = list(line_glyphs.keys())
multi_choice = MultiChoice(options=options, title="Find:", width=300)
multi_choice.js_on_change(
"value",
CustomJS(code=code, args=args),
)
return multi_choice
x_data = numpy.arange(-20, 20, 0.1)
palette = bokeh.palettes.Category10[10]
fig = figure(x_axis_label="x", y_axis_label="y", width=600, height=400)
line_glyphs: dict[str, GlyphRenderer] = {}
for i in range(10):
legend_label = f"y=sin(x + {i})"
line_glyphs[legend_label] = fig.line(
x_data,
numpy.sin(x_data + i),
color=palette[i],
legend_label=legend_label,
line_width=DEFAULT_LINE_WIDTH,
)
fig.legend.click_policy = "hide"
# 凡例をグラフの外に配置する
legend = fig.legend[0]
fig.add_layout(legend, "left")
output_file("graph.html")
multi_choice_widget = create_multi_choice_widget(line_glyphs)
save([fig, multi_choice_widget])
折れ線を選択すると、線が太くなり目立つようになりました。また凡例に表示されている線も自動的に太くなりました。
関連するサイト