From 61026198bbfd7bc056b6b255ce0dd3d0dd0dc4f2 Mon Sep 17 00:00:00 2001 From: Mateusz Paprocki Date: Wed, 28 Apr 2021 12:02:01 +0200 Subject: [PATCH 1/2] Unify {Figure,Toolbar}.active_* properties --- bokeh/models/tools.py | 2 +- bokeh/plotting/_tools.py | 35 ++++++++++++++++--------- bokeh/plotting/figure.py | 16 +++++++---- bokeh/plotting/gmap.py | 4 +-- bokehjs/src/lib/models/tools/toolbar.ts | 18 ++++++------- 5 files changed, 46 insertions(+), 29 deletions(-) diff --git a/bokeh/models/tools.py b/bokeh/models/tools.py index 937f7852ce8..96d6c2798ee 100644 --- a/bokeh/models/tools.py +++ b/bokeh/models/tools.py @@ -314,7 +314,7 @@ class Toolbar(ToolbarBase): Specify a tap/click tool to be active when the plot is displayed. """) - active_multi: tp.Union[Literal["auto"], GestureTool, None] = Nullable(Instance(GestureTool), help=""" + active_multi: tp.Union[Literal["auto"], GestureTool, None] = Either(Null, Auto, Instance(GestureTool), default="auto", help=""" Specify an active multi-gesture tool, for instance an edit tool or a range tool. diff --git a/bokeh/plotting/_tools.py b/bokeh/plotting/_tools.py index 53c8b035753..1fa243776b1 100644 --- a/bokeh/plotting/_tools.py +++ b/bokeh/plotting/_tools.py @@ -44,6 +44,7 @@ ) from ..models.tools import ( Drag, + GestureTool, InspectTool, Scroll, Tap, @@ -72,18 +73,21 @@ ActiveInspect = Union[List[InspectTool], InspectTool, Auto, str, None] ActiveScroll = Union[Scroll, Auto, str, None] ActiveTap = Union[Tap, Auto, str, None] +ActiveMulti = Union[GestureTool, Auto, str, None] def process_active_tools(toolbar: Toolbar, tool_map: Dict[str, Tool], - active_drag: ActiveDrag, active_inspect: ActiveInspect, active_scroll: ActiveScroll, active_tap: ActiveTap) -> None: + active_drag: ActiveDrag, active_inspect: ActiveInspect, active_scroll: ActiveScroll, + active_tap: ActiveTap, active_multi: ActiveMulti) -> None: """ Adds tools to the plot object Args: toolbar (Toolbar): instance of a Toolbar object tools_map (dict[str]): tool_map from _process_tools_arg - active_drag (str or Tool): the tool to set active for drag - active_inspect (str or Tool): the tool to set active for inspect - active_scroll (str or Tool): the tool to set active for scroll - active_tap (str or Tool): the tool to set active for tap + active_drag (str, None, "auto" or Tool): the tool to set active for drag + active_inspect (str, None, "auto", Tool or Tool[]): the tool to set active for inspect + active_scroll (str, None, "auto" or Tool): the tool to set active for scroll + active_tap (str, None, "auto" or Tool): the tool to set active for tap + active_multi (str, None, "auto" or Tool): the tool to set active for tap Returns: None @@ -91,12 +95,12 @@ def process_active_tools(toolbar: Toolbar, tool_map: Dict[str, Tool], Note: This function sets properties on Toolbar """ - if active_drag in ['auto', None] or isinstance(active_drag, Tool): + if active_drag in ["auto", None] or isinstance(active_drag, Tool): toolbar.active_drag = cast(Any, active_drag) elif active_drag in tool_map: toolbar.active_drag = cast(Any, tool_map[active_drag]) else: - raise ValueError("Got unknown %r for 'active_drag', which was not a string supplied in 'tools' argument" % active_drag) + raise ValueError(f"Got unknown {active_drag!r} for 'active_drag', which was not a string supplied in 'tools' argument") if active_inspect in ["auto", None] or isinstance(active_inspect, Tool) or \ (isinstance(active_inspect, list) and all(isinstance(t, Tool) for t in active_inspect)): @@ -104,21 +108,28 @@ def process_active_tools(toolbar: Toolbar, tool_map: Dict[str, Tool], elif isinstance(active_inspect, str) and active_inspect in tool_map: toolbar.active_inspect = cast(Any, tool_map[active_inspect]) else: - raise ValueError("Got unknown %r for 'active_inspect', which was not a string supplied in 'tools' argument" % active_scroll) + raise ValueError(f"Got unknown {active_inspect!r} for 'active_inspect', which was not a string supplied in 'tools' argument") - if active_scroll in ['auto', None] or isinstance(active_scroll, Tool): + if active_scroll in ["auto", None] or isinstance(active_scroll, Tool): toolbar.active_scroll = cast(Any, active_scroll) elif active_scroll in tool_map: toolbar.active_scroll = cast(Any, tool_map[active_scroll]) else: - raise ValueError("Got unknown %r for 'active_scroll', which was not a string supplied in 'tools' argument" % active_scroll) + raise ValueError(f"Got unknown {active_scroll!r} for 'active_scroll', which was not a string supplied in 'tools' argument") - if active_tap in ['auto', None] or isinstance(active_tap, Tool): + if active_tap in ["auto", None] or isinstance(active_tap, Tool): toolbar.active_tap = cast(Any, active_tap) elif active_tap in tool_map: toolbar.active_tap = cast(Any, tool_map[active_tap]) else: - raise ValueError("Got unknown %r for 'active_tap', which was not a string supplied in 'tools' argument" % active_tap) + raise ValueError(f"Got unknown {active_tap!r} for 'active_tap', which was not a string supplied in 'tools' argument") + + if active_multi in ["auto", None] or isinstance(active_multi, Tool): + toolbar.active_multi = cast(Any, active_multi) + elif active_multi in tool_map: + toolbar.active_multi = cast(Any, tool_map[active_multi]) + else: + raise ValueError(f"Got unknown {active_multi!r} for 'active_multi', which was not a string supplied in 'tools' argument") def process_tools_arg(plot: Plot, tools: Union[str, Sequence[Union[Tool, str]]], tooltips: Optional[Union[str, Tuple[str, str]]] = None) -> Tuple[List[Tool], Dict[str, Tool]]: diff --git a/bokeh/plotting/figure.py b/bokeh/plotting/figure.py index 6e3764a18e1..cf3804507d3 100644 --- a/bokeh/plotting/figure.py +++ b/bokeh/plotting/figure.py @@ -41,6 +41,7 @@ ) from ..models.tools import ( Drag, + GestureTool, InspectTool, Scroll, Tap, @@ -181,7 +182,8 @@ def __init__(self, *arg, **kw): tool_objs, tool_map = process_tools_arg(self, opts.tools, opts.tooltips) self.add_tools(*tool_objs) - process_active_tools(self.toolbar, tool_map, opts.active_drag, opts.active_inspect, opts.active_scroll, opts.active_tap) + process_active_tools(self.toolbar, tool_map, + opts.active_drag, opts.active_inspect, opts.active_scroll, opts.active_tap, opts.active_multi) @glyph_method(glyphs.AnnularWedge) def annular_wedge(self, **kwargs): @@ -1643,22 +1645,26 @@ class FigureOptions(Options): A label for the y-axis. """) - active_drag = Either(Auto, String, Instance(Drag), default="auto", help=""" + active_drag = Either(Null, Auto, String, Instance(Drag), default="auto", help=""" Which drag tool should initially be active. """) - active_inspect = Either(Auto, String, Instance(InspectTool), Seq(Instance(InspectTool)), default="auto", help=""" + active_inspect = Either(Null, Auto, String, Instance(InspectTool), Seq(Instance(InspectTool)), default="auto", help=""" Which drag tool should initially be active. """) - active_scroll = Either(Auto, String, Instance(Scroll), default="auto", help=""" + active_scroll = Either(Null, Auto, String, Instance(Scroll), default="auto", help=""" Which scroll tool should initially be active. """) - active_tap = Either(Auto, String, Instance(Tap), default="auto", help=""" + active_tap = Either(Null, Auto, String, Instance(Tap), default="auto", help=""" Which tap tool should initially be active. """) + active_multi = Either(Null, Auto, String, Instance(GestureTool), default="auto", help=""" + Specify an active multi-gesture tool, for instance an edit tool or a range tool. + """) + x_axis_type = Either(Null, Auto, Enum("linear", "log", "datetime", "mercator"), default="auto", help=""" The type of the x-axis. """) diff --git a/bokeh/plotting/gmap.py b/bokeh/plotting/gmap.py index 90dde0c8206..283d018ae97 100644 --- a/bokeh/plotting/gmap.py +++ b/bokeh/plotting/gmap.py @@ -105,8 +105,8 @@ def __init__(self, **kw): tool_objs, tool_map = process_tools_arg(self, opts.tools) self.add_tools(*tool_objs) - process_active_tools(self.toolbar, tool_map, opts.active_drag, opts.active_inspect, opts.active_scroll, opts.active_tap) - + process_active_tools(self.toolbar, tool_map, + opts.active_drag, opts.active_inspect, opts.active_scroll, opts.active_tap, opts.active_multi) annular_wedge = Figure.annular_wedge diff --git a/bokehjs/src/lib/models/tools/toolbar.ts b/bokehjs/src/lib/models/tools/toolbar.ts index 45463b0e14b..e22cb9b3ad0 100644 --- a/bokehjs/src/lib/models/tools/toolbar.ts +++ b/bokehjs/src/lib/models/tools/toolbar.ts @@ -23,7 +23,7 @@ type ActiveGestureToolsProps = { active_drag: p.Property active_scroll: p.Property active_tap: p.Property - active_multi: p.Property + active_multi: p.Property } type ActiveToolsProps = ActiveGestureToolsProps & { @@ -38,7 +38,7 @@ export namespace Toolbar { export interface Toolbar extends Toolbar.Attrs {} -const _get_active_attr = (et: string): keyof ActiveGestureToolsProps | null => { +function _get_active_attr(et: string): keyof ActiveGestureToolsProps | null { switch (et) { case 'tap': return 'active_tap' case 'pan': return 'active_drag' @@ -49,7 +49,7 @@ const _get_active_attr = (et: string): keyof ActiveGestureToolsProps | null => { return null } -const _supports_auto = (et: string) => { +function _supports_auto(et: string): boolean { return et == 'tap' || et == 'pan' } @@ -63,12 +63,12 @@ export class Toolbar extends ToolbarBase { static init_Toolbar(): void { this.prototype.default_view = ToolbarBaseView - this.define(({Or, Ref, Auto, Null, Nullable}) => ({ - active_drag: [ Or(Ref(Drag), Auto, Null), "auto" ], - active_inspect: [ Or(Ref(Inspection), Auto, Null), "auto" ], - active_scroll: [ Or(Ref(Scroll), Auto, Null), "auto" ], - active_tap: [ Or(Ref(Tap), Auto, Null), "auto" ], - active_multi: [ Nullable(Ref(GestureTool)), null ], + this.define(({Or, Ref, Auto, Null}) => ({ + active_drag: [ Or(Ref(Drag), Auto, Null), "auto" ], + active_inspect: [ Or(Ref(Inspection), Auto, Null), "auto" ], + active_scroll: [ Or(Ref(Scroll), Auto, Null), "auto" ], + active_tap: [ Or(Ref(Tap), Auto, Null), "auto" ], + active_multi: [ Or(Ref(GestureTool), Auto, Null), "auto" ], })) } From 0f30e87af87a282fc7ba7fce56cf2987165b3947 Mon Sep 17 00:00:00 2001 From: Mateusz Paprocki Date: Wed, 28 Apr 2021 21:50:04 +0200 Subject: [PATCH 2/2] Unify FigureOptions and GMapFigureOptions --- bokeh/plotting/figure.py | 47 +++++++++++-------- bokeh/plotting/gmap.py | 97 ++++++++++------------------------------ 2 files changed, 52 insertions(+), 92 deletions(-) diff --git a/bokeh/plotting/figure.py b/bokeh/plotting/figure.py index cf3804507d3..8201fa8deb6 100644 --- a/bokeh/plotting/figure.py +++ b/bokeh/plotting/figure.py @@ -182,8 +182,15 @@ def __init__(self, *arg, **kw): tool_objs, tool_map = process_tools_arg(self, opts.tools, opts.tooltips) self.add_tools(*tool_objs) - process_active_tools(self.toolbar, tool_map, - opts.active_drag, opts.active_inspect, opts.active_scroll, opts.active_tap, opts.active_multi) + process_active_tools( + self.toolbar, + tool_map, + opts.active_drag, + opts.active_inspect, + opts.active_scroll, + opts.active_tap, + opts.active_multi, + ) @glyph_method(glyphs.AnnularWedge) def annular_wedge(self, **kwargs): @@ -1607,20 +1614,12 @@ def markers(): # This class itself is intentionally undocumented (it is used to generate # documentation elsewhere) -class FigureOptions(Options): +class BaseFigureOptions(Options): tools = Either(String, Seq(Either(String, Instance(Tool))), default=DEFAULT_TOOLS, help=""" Tools the plot should start with. """) - x_range = Any(help=""" - Customize the x-range of the plot. - """) - - y_range = Any(help=""" - Customize the y-range of the plot. - """) - x_minor_ticks = Either(Auto, Int, default="auto", help=""" Number of minor ticks between adjacent x-axis major ticks. """) @@ -1665,14 +1664,6 @@ class FigureOptions(Options): Specify an active multi-gesture tool, for instance an edit tool or a range tool. """) - x_axis_type = Either(Null, Auto, Enum("linear", "log", "datetime", "mercator"), default="auto", help=""" - The type of the x-axis. - """) - - y_axis_type = Either(Null, Auto, Enum("linear", "log", "datetime", "mercator"), default="auto", help=""" - The type of the y-axis. - """) - tooltips = Either(Null, String, List(Tuple(String, String)), help=""" An optional argument to configure tooltips for the Figure. This argument accepts the same values as the ``HoverTool.tooltips`` property. If a hover @@ -1682,6 +1673,24 @@ class FigureOptions(Options): and added. """) +class FigureOptions(BaseFigureOptions): + + x_range = Any(help=""" + Customize the x-range of the plot. + """) + + y_range = Any(help=""" + Customize the y-range of the plot. + """) + + x_axis_type = Either(Null, Auto, Enum("linear", "log", "datetime", "mercator"), default="auto", help=""" + The type of the x-axis. + """) + + y_axis_type = Either(Null, Auto, Enum("linear", "log", "datetime", "mercator"), default="auto", help=""" + The type of the y-axis. + """) + #----------------------------------------------------------------------------- # Private API #----------------------------------------------------------------------------- diff --git a/bokeh/plotting/gmap.py b/bokeh/plotting/gmap.py index 283d018ae97..2073a456a86 100644 --- a/bokeh/plotting/gmap.py +++ b/bokeh/plotting/gmap.py @@ -16,16 +16,6 @@ #----------------------------------------------------------------------------- # Bokeh imports -from ..core.enums import HorizontalLocation, VerticalLocation -from ..core.properties import ( - Auto, - Either, - Enum, - Instance, - Int, - Seq, - String, -) from ..models import ( GMapPlot, LinearAxis, @@ -33,17 +23,10 @@ MercatorTickFormatter, Range1d, Title, - Tool, -) -from ..models.tools import ( - Drag, - InspectTool, - Scroll, - Tap, ) -from ..util.options import Options +from ._plot import _get_num_minor_ticks from ._tools import process_active_tools, process_tools_arg -from .figure import Figure +from .figure import BaseFigureOptions, Figure #----------------------------------------------------------------------------- # Globals and constants @@ -95,18 +78,29 @@ def __init__(self, **kw): super().__init__(x_range=Range1d(), y_range=Range1d(), **kw) - xf = MercatorTickFormatter(dimension="lon") - xt = MercatorTicker(dimension="lon") - self.add_layout(LinearAxis(formatter=xf, ticker=xt), 'below') + if opts.x_axis_location is not None: + xf = MercatorTickFormatter(dimension="lon") + xt = MercatorTicker(dimension="lon") + xt.num_minor_ticks = _get_num_minor_ticks(LinearAxis, opts.x_minor_ticks) + self.add_layout(LinearAxis(formatter=xf, ticker=xt, axis_label=opts.x_axis_label), opts.x_axis_location) - yf = MercatorTickFormatter(dimension="lat") - yt = MercatorTicker(dimension="lat") - self.add_layout(LinearAxis(formatter=yf, ticker=yt), 'left') + if opts.y_axis_location is not None: + yf = MercatorTickFormatter(dimension="lat") + yt = MercatorTicker(dimension="lat") + yt.num_minor_ticks = _get_num_minor_ticks(LinearAxis, opts.y_minor_ticks) + self.add_layout(LinearAxis(formatter=yf, ticker=yt, axis_label=opts.y_axis_label), opts.y_axis_location) - tool_objs, tool_map = process_tools_arg(self, opts.tools) + tool_objs, tool_map = process_tools_arg(self, opts.tools, opts.tooltips) self.add_tools(*tool_objs) - process_active_tools(self.toolbar, tool_map, - opts.active_drag, opts.active_inspect, opts.active_scroll, opts.active_tap, opts.active_multi) + process_active_tools( + self.toolbar, + tool_map, + opts.active_drag, + opts.active_inspect, + opts.active_scroll, + opts.active_tap, + opts.active_multi, + ) annular_wedge = Figure.annular_wedge @@ -245,51 +239,8 @@ def gmap(google_api_key, map_options, **kwargs): # Dev API #----------------------------------------------------------------------------- -class GMapFigureOptions(Options): - - tools = Either(String, Seq(Either(String, Instance(Tool))), default=DEFAULT_TOOLS, help=""" - Tools the plot should start with. - """) - - x_minor_ticks = Either(Auto, Int, default="auto", help=""" - Number of minor ticks between adjacent x-axis major ticks. - """) - - y_minor_ticks = Either(Auto, Int, default="auto", help=""" - Number of minor ticks between adjacent y-axis major ticks. - """) - - x_axis_location = Enum(VerticalLocation, default="below", help=""" - Where the x-axis should be located. - """) - - y_axis_location = Enum(HorizontalLocation, default="left", help=""" - Where the y-axis should be located. - """) - - x_axis_label = String(default="", help=""" - A label for the x-axis. - """) - - y_axis_label = String(default="", help=""" - A label for the y-axis. - """) - - active_drag = Either(Auto, String, Instance(Drag), default="auto", help=""" - Which drag tool should initially be active. - """) - - active_inspect = Either(Auto, String, Instance(InspectTool), Seq(Instance(InspectTool)), default="auto", help=""" - Which drag tool should initially be active. - """) - - active_scroll = Either(Auto, String, Instance(Scroll), default="auto", help=""" - Which scroll tool should initially be active. - """) - - active_tap = Either(Auto, String, Instance(Tap), default="auto", help=""" - Which tap tool should initially be active. - """) +class GMapFigureOptions(BaseFigureOptions): + pass #----------------------------------------------------------------------------- # Private API