Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow changes to columns in bokeh CDS #2666

Merged
merged 6 commits into from
May 8, 2018
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ install:
- conda info -a
- conda create -q -n test-environment python=$TRAVIS_PYTHON_VERSION flake8 scipy=1.0.0 numpy freetype nose pandas=0.22.0 jupyter ipython=5.4.1 param matplotlib=2.1.2 xarray
- source activate test-environment
- conda install -c conda-forge iris plotly flexx ffmpeg --quiet
- conda install -c conda-forge iris plotly flexx ffmpeg netcdf4=1.3.1 --quiet
- conda install -c bokeh datashader dask bokeh=0.12.15 selenium
- if [[ "$TRAVIS_PYTHON_VERSION" == "3.4" ]]; then
conda install python=3.4.3;
Expand Down
12 changes: 12 additions & 0 deletions holoviews/plotting/bokeh/plot.py
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,18 @@ def _update_datasource(self, source, data):
source.data.update(converted_data)
else:
source.stream(data, stream.length)
return

# Determine if the CDS.data requires a full update or simply needs
# to be updated, this is done by determining whether newly added
# or not updated columns have the same length
new_length = [len(v) for v in data.values() if isinstance(v, (list, np.ndarray))]
length = [len(v) for v in source.data.values() if isinstance(v, (list, np.ndarray))]
not_updated = [k for k in source.data if k not in data]
new = [k for k in data if k not in source.data]
if ((not_updated and new_length and any(len(source.data[n]) != new_length[0] for n in not_updated))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure you need the initial not_updated as any([]) evaluates to false.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that is also true for the check against new.

or (new and length and any(len(data[n]) != length[0] for n in new))):
source.data = data
else:
source.data.update(data)

Expand Down
2 changes: 2 additions & 0 deletions holoviews/plotting/bokeh/tabular.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,4 +121,6 @@ def update_frame(self, key, ranges=None, plot=None):
source = self.handles['source']
style = self.lookup_options(element, 'style')[self.cyclic_index]
data, _, style = self.get_data(element, ranges, style)
columns = self._get_columns(element, data)
self.handles['plot'].columns = columns
self._update_datasource(source, data)
20 changes: 20 additions & 0 deletions tests/plotting/bokeh/testelementplot.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,26 @@ def test_element_grid_options(self):
self.assertEqual(plot.state.ygrid[0].grid_line_width, 1.5)
self.assertEqual(plot.state.ygrid[0].bounds, (0.3, 0.7))

def test_change_cds_columns(self):
lengths = {'a': 1, 'b': 2, 'c': 3}
curve = DynamicMap(lambda a: Curve(range(lengths[a]), a), kdims=['a']).redim.values(a=['a', 'b', 'c'])
plot = bokeh_renderer.get_plot(curve)
self.assertEqual(sorted(plot.handles['source'].data.keys()), ['a', 'y'])
self.assertEqual(plot.state.xaxis[0].axis_label, 'a')
plot.update(('b',))
self.assertEqual(sorted(plot.handles['source'].data.keys()), ['b', 'y'])
self.assertEqual(plot.state.xaxis[0].axis_label, 'b')

def test_update_cds_columns(self):
curve = DynamicMap(lambda a: Curve(range(10), a), kdims=['a']).redim.values(a=['a', 'b', 'c'])
plot = bokeh_renderer.get_plot(curve)
self.assertEqual(sorted(plot.handles['source'].data.keys()), ['a', 'y'])
self.assertEqual(plot.state.xaxis[0].axis_label, 'a')
plot.update(('b',))
self.assertEqual(sorted(plot.handles['source'].data.keys()), ['a', 'b', 'y'])
self.assertEqual(plot.state.xaxis[0].axis_label, 'b')



class TestColorbarPlot(TestBokehPlot):

Expand Down
11 changes: 11 additions & 0 deletions tests/plotting/bokeh/testtabular.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from unittest import SkipTest

from holoviews.core.options import Store
from holoviews.core.spaces import DynamicMap
from holoviews.element import Table
from holoviews.element.comparison import ComparisonTestCase
from holoviews.streams import CDSStream
Expand Down Expand Up @@ -62,3 +63,13 @@ def test_table_plot_callback(self):
plot = bokeh_renderer.get_plot(table)
self.assertEqual(len(plot.callbacks), 1)
self.assertIsInstance(plot.callbacks[0], CDSCallback)

def test_table_change_columns(self):
lengths = {'a': 1, 'b': 2, 'c': 3}
table = DynamicMap(lambda a: Table(range(lengths[a]), a), kdims=['a']).redim.values(a=['a', 'b', 'c'])
plot = bokeh_renderer.get_plot(table)
self.assertEqual(sorted(plot.handles['source'].data.keys()), ['a'])
self.assertEqual(plot.handles['plot'].columns[0].title, 'a')
plot.update(('b',))
self.assertEqual(sorted(plot.handles['source'].data.keys()), ['b'])
self.assertEqual(plot.handles['plot'].columns[0].title, 'b')