diff --git a/holoviews/plotting/bokeh/element.py b/holoviews/plotting/bokeh/element.py index a4b0f9989f..f96d7ea714 100644 --- a/holoviews/plotting/bokeh/element.py +++ b/holoviews/plotting/bokeh/element.py @@ -6,7 +6,6 @@ from bokeh.models import Range, HoverTool, Renderer from bokeh.models.tickers import Ticker, BasicTicker, FixedTicker from bokeh.models.widgets import Panel, Tabs -from distutils.version import LooseVersion try: from bokeh import mpl @@ -25,6 +24,11 @@ from .plot import BokehPlot from .util import mpl_to_bokeh, convert_datetime, update_plot, bokeh_version +if bokeh_version >= '0.12': + from bokeh.models import FuncTickFormatter +else: + FuncTickFormatter = None + # Define shared style properties for bokeh plots line_properties = ['line_width', 'line_color', 'line_alpha', @@ -270,8 +274,7 @@ def _init_plot(self, key, element, plots, ranges=None): else: title = '' - if LooseVersion(bokeh.__version__) >= LooseVersion('0.10'): - properties['webgl'] = self.renderer.webgl + properties['webgl'] = self.renderer.webgl return bokeh.plotting.Figure(x_axis_type=x_axis_type, y_axis_type=y_axis_type, title=title, tools=tools, **properties) @@ -325,7 +328,7 @@ def _init_axes(self, plot): plot.yaxis[:] = plot.right - def _axis_properties(self, axis, key, plot, element): + def _axis_properties(self, axis, key, plot, element, ax_mapping={'x': 0, 'y': 1}): """ Returns a dictionary of axis properties depending on the specified axis. @@ -351,6 +354,29 @@ def _axis_properties(self, axis, key, plot, element): pass else: axis_props['ticker'] = FixedTicker(ticks=ticker) + + dim = element.get_dimension(ax_mapping[axis]) + if FuncTickFormatter is not None and ax_mapping and dim: + formatter = None + if dim.value_format: + formatter = dim.value_format + elif dim.type in dim.type_formatters: + formatter = dim.type_formatters[dim.type] + if formatter: + msg = ('%s dimension formatter could not be ' + 'converted to tick formatter. ' % dim.name) + try: + formatter = FuncTickFormatter.from_py_func(formatter) + except RuntimeError: + self.warning(msg+'Ensure Flexx is installed ' + '("conda install -c bokeh flexx" or ' + '"pip install flexx")') + except Exception as e: + error = 'Pyscript raised an error: {0}'.format(e) + error = error.replace('%', '%%') + self.warning(msg+error) + else: + axis_props['formatter'] = formatter return axis_props diff --git a/holoviews/plotting/mpl/util.py b/holoviews/plotting/mpl/util.py index 5fa833e2a7..51e2e07ec1 100644 --- a/holoviews/plotting/mpl/util.py +++ b/holoviews/plotting/mpl/util.py @@ -1,4 +1,5 @@ import re +import inspect import numpy as np from matplotlib import ticker @@ -14,7 +15,13 @@ def wrap_formatter(formatter): if isinstance(formatter, ticker.Formatter): return formatter elif callable(formatter): - return ticker.FuncFormatter(formatter) + args = [arg for arg in inspect.getargspec(formatter).args + if arg != 'self'] + wrapped = formatter + if len(args) == 1: + def wrapped(val, pos=None): + return formatter(val) + return ticker.FuncFormatter(wrapped) elif isinstance(formatter, basestring): if re.findall(r"\{(\w+)\}", formatter): return ticker.StrMethodFormatter(formatter)