Source code for arviz_plots.backend.bokeh.legend

"""Bokeh manual legend generation."""
import warnings

from bokeh.models import Legend

from .core import expand_aesthetic_aliases


@expand_aesthetic_aliases
def dealiase_line_kwargs(**kwargs):
    """Convert arviz common interface properties to bokeh ones."""
    prop_map = {"width": "line_width", "linestyle": "line_dash"}
    return {prop_map.get(key, key): value for key, value in kwargs.items()}


[docs] def legend( plot_collection, kwarg_list, label_list, title=None, visual_type="line", visual_kwargs=None, legend_dim=None, # pylint: disable=unused-argument update_visuals=False, # pylint: disable=unused-argument legend_target=None, side="right", **kwargs, ): """Generate a legend on a figure given lists of labels and property kwargs. Parameters ---------- plot_collection : PlotCollection kwarg_list : sequence of mapping Sequence with length equal to the number of entries to add to the legend. The elements in the list are the kwargs to use when defining the legend miniatures. label_list : sequence of str Sequence with length equal to the number of entries to add to the legend. The elements in the list are the labels to give each miniature in the legend. title : str, optional The title to give the legend. visual_type : {"line", "scatter", "rectangle"}, default "line" visual_kwargs : mapping, optional Passed to all visuals when generating legend miniatures. For "line" visual type passed to :meth:`bokeh.plotting.figure.line` legend_dim : str or sequence of str, optional Dimension or dimensions whose mappings should be used to generate the legend. update_visuals : bool, optional If relevant for the backend, update objects representing :term:`visual` elements of the plot to improve or allow interactivity for the legend. legend_target : (int, int), default (0, -1) Row and colum indicators of the :term:`plot` where the legend will be placed. Bokeh does not support :term:`figure` level legend. side : str, optional Side of the plot on which to place the legend. Use "center" to put the legend inside the plotting area. **kwargs Passed to :class:`bokeh.models.Legend` """ if visual_kwargs is None: visual_kwargs = {} if legend_target is None: legend_target = (0, -1) if side == "right": kwargs.setdefault("margin", -55) target_plot = plot_collection.iget_target(*legend_target) if target_plot.legend: warnings.warn("This target plot already contains a legend") glyph_list = [] if visual_type == "line": visual_fun = target_plot.line kwarg_list = [dealiase_line_kwargs(**kws) for kws in kwarg_list] else: raise NotImplementedError("Only line type legends supported for now") for kws in kwarg_list: glyph = visual_fun(**{**visual_kwargs, **kws}) glyph_list.append(glyph) leg = Legend( items=[(str(label), [glyph]) for label, glyph in zip(label_list, glyph_list)], title=title, **kwargs, ) target_plot.add_layout(leg, side) return leg