From f08a089612acaffca9abfc095721ef2cce8880e5 Mon Sep 17 00:00:00 2001
From: Philipp Rudiger
Date: Wed, 22 Jun 2016 14:50:18 +0100
Subject: [PATCH 1/4] Added support for tick formatters in bokeh
---
holoviews/plotting/bokeh/element.py | 29 +++++++++++++++++++++++++----
1 file changed, 25 insertions(+), 4 deletions(-)
diff --git a/holoviews/plotting/bokeh/element.py b/holoviews/plotting/bokeh/element.py
index a4b0f9989f..4830c38803 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,24 @@ def _axis_properties(self, axis, key, plot, element):
pass
else:
axis_props['ticker'] = FixedTicker(ticks=ticker)
+
+ dim = element.get_dimension(ax_mapping[axis])
+ if 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:
+ try:
+ formatter = FuncTickFormatter.from_py_func(formatter)
+ except:
+ self.warning('%s dimension formatter could not be '
+ 'converted to tick formatter. Ensure '
+ 'flexx is installed and pyscript can '
+ 'compile the function.' % dim.name)
+ else:
+ axis_props['formatter'] = formatter
return axis_props
From 46b785be98d5f9e25a5bbf0b747fb2bed74b71e9 Mon Sep 17 00:00:00 2001
From: Philipp Rudiger
Date: Wed, 22 Jun 2016 15:27:00 +0100
Subject: [PATCH 2/4] Improved bokeh tick formatter error messages
---
holoviews/plotting/bokeh/element.py | 15 ++++++++++-----
1 file changed, 10 insertions(+), 5 deletions(-)
diff --git a/holoviews/plotting/bokeh/element.py b/holoviews/plotting/bokeh/element.py
index 4830c38803..5659b32d34 100644
--- a/holoviews/plotting/bokeh/element.py
+++ b/holoviews/plotting/bokeh/element.py
@@ -363,13 +363,18 @@ def _axis_properties(self, axis, key, plot, element, ax_mapping={'x': 0, 'y': 1}
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:
- self.warning('%s dimension formatter could not be '
- 'converted to tick formatter. Ensure '
- 'flexx is installed and pyscript can '
- 'compile the function.' % dim.name)
+ 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
From 6238c52ea2d72207f399c85b38753612fa2f8593 Mon Sep 17 00:00:00 2001
From: Philipp Rudiger
Date: Wed, 22 Jun 2016 15:29:34 +0100
Subject: [PATCH 3/4] Ensured bokeh 0.11 does not try to use FuncTickFormatter
---
holoviews/plotting/bokeh/element.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/holoviews/plotting/bokeh/element.py b/holoviews/plotting/bokeh/element.py
index 5659b32d34..f96d7ea714 100644
--- a/holoviews/plotting/bokeh/element.py
+++ b/holoviews/plotting/bokeh/element.py
@@ -356,7 +356,7 @@ def _axis_properties(self, axis, key, plot, element, ax_mapping={'x': 0, 'y': 1}
axis_props['ticker'] = FixedTicker(ticks=ticker)
dim = element.get_dimension(ax_mapping[axis])
- if ax_mapping and dim:
+ if FuncTickFormatter is not None and ax_mapping and dim:
formatter = None
if dim.value_format:
formatter = dim.value_format
From 35a16586e8521a2da38800a89e4c1344d9597676 Mon Sep 17 00:00:00 2001
From: Philipp Rudiger
Date: Mon, 27 Jun 2016 14:27:15 +0100
Subject: [PATCH 4/4] Allow single argument function as matplotlib tick
formatter
---
holoviews/plotting/mpl/util.py | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
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)