Skip to content

Commit

Permalink
Merge 8c25146 into 6aa4f0b
Browse files Browse the repository at this point in the history
  • Loading branch information
philippjfr committed Feb 18, 2018
2 parents 6aa4f0b + 8c25146 commit 64ee6ec
Show file tree
Hide file tree
Showing 88 changed files with 2,276 additions and 2,061 deletions.
Empty file added tests/core/__init__.py
Empty file.
Empty file added tests/core/data/__init__.py
Empty file.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
2 changes: 1 addition & 1 deletion tests/testcallable.py → tests/core/testcallable.py
Expand Up @@ -13,7 +13,7 @@
from holoviews.operation import contours
from functools import partial

from . import LoggingComparisonTestCase
from .. import LoggingComparisonTestCase

class CallableClass(object):

Expand Down
File renamed without changes.
File renamed without changes.
2 changes: 1 addition & 1 deletion tests/testdimensions.py → tests/core/testdimensions.py
Expand Up @@ -4,7 +4,7 @@
from unittest import SkipTest
from holoviews.core import Dimensioned, Dimension
from holoviews.element.comparison import ComparisonTestCase
from . import LoggingComparisonTestCase
from .. import LoggingComparisonTestCase

import numpy as np
try:
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Empty file added tests/ipython/__init__.py
Empty file.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
34 changes: 34 additions & 0 deletions tests/plotting/bokeh/testannotationplot.py
@@ -0,0 +1,34 @@
from holoviews.element import HLine, VLine

from .testplot import TestBokehPlot, bokeh_renderer


class TestHVLinePlot(TestBokehPlot):

def test_hline_invert_axes(self):
hline = HLine(1.1).opts(plot=dict(invert_axes=True))
plot = bokeh_renderer.get_plot(hline)
span = plot.handles['glyph']
self.assertEqual(span.dimension, 'height')
self.assertEqual(span.location, 1.1)

def test_hline_plot(self):
hline = HLine(1.1)
plot = bokeh_renderer.get_plot(hline)
span = plot.handles['glyph']
self.assertEqual(span.dimension, 'width')
self.assertEqual(span.location, 1.1)

def test_vline_invert_axes(self):
vline = VLine(1.1).opts(plot=dict(invert_axes=True))
plot = bokeh_renderer.get_plot(vline)
span = plot.handles['glyph']
self.assertEqual(span.dimension, 'width')
self.assertEqual(span.location, 1.1)

def test_vline_plot(self):
vline = VLine(1.1)
plot = bokeh_renderer.get_plot(vline)
span = plot.handles['glyph']
self.assertEqual(span.dimension, 'height')
self.assertEqual(span.location, 1.1)
81 changes: 81 additions & 0 deletions tests/plotting/bokeh/testbarplot.py
@@ -0,0 +1,81 @@
import numpy as np

from holoviews.element import Bars

from .testplot import TestBokehPlot, bokeh_renderer


class TestBarPlot(TestBokehPlot):

def test_bars_hover_ensure_kdims_sanitized(self):
obj = Bars(np.random.rand(10,2), kdims=['Dim with spaces'])
obj = obj(plot={'tools': ['hover']})
self._test_hover_info(obj, [('Dim with spaces', '@{Dim_with_spaces}'), ('y', '@{y}')])

def test_bars_hover_ensure_vdims_sanitized(self):
obj = Bars(np.random.rand(10,2), vdims=['Dim with spaces'])
obj = obj(plot={'tools': ['hover']})
self._test_hover_info(obj, [('x', '@{x}'), ('Dim with spaces', '@{Dim_with_spaces}')])

def test_bars_suppress_legend(self):
bars = Bars([('A', 1), ('B', 2)]).opts(plot=dict(show_legend=False))
plot = bokeh_renderer.get_plot(bars)
plot.initialize_plot()
fig = plot.state
self.assertEqual(len(fig.legend), 0)

def test_empty_bars(self):
bars = Bars([], kdims=['x', 'y'], vdims=['z']).opts(plot=dict(group_index=1))
plot = bokeh_renderer.get_plot(bars)
plot.initialize_plot()
source = plot.handles['source']
for v in source.data.values():
self.assertEqual(len(v), 0)

def test_bars_grouped_categories(self):
bars = Bars([('A', 0, 1), ('A', 1, -1), ('B', 0, 2)],
kdims=['Index', 'Category'], vdims=['Value'])
plot = bokeh_renderer.get_plot(bars)
source = plot.handles['source']
self.assertEqual([tuple(x) for x in source.data['xoffsets']],
[('A', '0'), ('B', '0'), ('A', '1')])
self.assertEqual(list(source.data['Category']), ['0', '0', '1'])
self.assertEqual(source.data['Value'], np.array([1, 2, -1]))
x_range = plot.handles['x_range']
self.assertEqual(x_range.factors, [('A', '0'), ('A', '1'), ('B', '0'), ('B', '1')])

def test_bars_positive_negative_mixed(self):
bars = Bars([('A', 0, 1), ('A', 1, -1), ('B', 0, 2)],
kdims=['Index', 'Category'], vdims=['Value'])
plot = bokeh_renderer.get_plot(bars.opts(plot=dict(stack_index=1)))
source = plot.handles['source']
self.assertEqual(list(source.data['Category']), ['1', '0', '0'])
self.assertEqual(list(source.data['Index']), ['A', 'A', 'B'])
self.assertEqual(source.data['top'], np.array([0, 1, 2]))
self.assertEqual(source.data['bottom'], np.array([-1, 0, 0]))

def test_bars_logy(self):
bars = Bars([('A', 1), ('B', 2), ('C', 3)],
kdims=['Index'], vdims=['Value'])
plot = bokeh_renderer.get_plot(bars.opts(plot=dict(logy=True)))
source = plot.handles['source']
glyph = plot.handles['glyph']
y_range = plot.handles['y_range']
self.assertEqual(list(source.data['Index']), ['A', 'B', 'C'])
self.assertEqual(source.data['Value'], np.array([1, 2, 3]))
self.assertEqual(glyph.bottom, 10**(np.log10(3)-2))
self.assertEqual(y_range.start, 10**(np.log10(3)-2))
self.assertEqual(y_range.end, 3.)

def test_bars_logy_explicit_range(self):
bars = Bars([('A', 1), ('B', 2), ('C', 3)],
kdims=['Index'], vdims=['Value']).redim.range(Value=(0.001, 3))
plot = bokeh_renderer.get_plot(bars.opts(plot=dict(logy=True)))
source = plot.handles['source']
glyph = plot.handles['glyph']
y_range = plot.handles['y_range']
self.assertEqual(list(source.data['Index']), ['A', 'B', 'C'])
self.assertEqual(source.data['Value'], np.array([1, 2, 3]))
self.assertEqual(glyph.bottom, 0.001)
self.assertEqual(y_range.start, 0.001)
self.assertEqual(y_range.end, 3.)
37 changes: 37 additions & 0 deletions tests/plotting/bokeh/testboxwhiskerplot.py
@@ -0,0 +1,37 @@
import datetime as dt

import numpy as np

from holoviews.element import BoxWhisker

from .testplot import TestBokehPlot, bokeh_renderer

try:
from bokeh.models import ColumnDataSource
except:
pass


class TestBoxWhiskerPlot(TestBokehPlot):

def test_box_whisker_datetime(self):
times = np.arange(dt.datetime(2017,1,1), dt.datetime(2017,2,1),
dt.timedelta(days=1))
box = BoxWhisker((times, np.random.rand(len(times))), kdims=['Date'])
plot = bokeh_renderer.get_plot(box)
formatted = [box.kdims[0].pprint_value(t) for t in times]
self.assertTrue(all(cds.data['index'][0] in formatted for cds in
plot.state.select(ColumnDataSource)
if len(cds.data.get('index', []))))

def test_box_whisker_hover(self):
xs, ys = np.random.randint(0, 5, 100), np.random.randn(100)
box = BoxWhisker((xs, ys), 'A').sort().opts(plot=dict(tools=['hover']))
plot = bokeh_renderer.get_plot(box)
src = plot.handles['vbar_1_source']
ys = box.aggregate(function=np.median).dimension_values('y')
hover_tool = plot.handles['hover']
self.assertEqual(src.data['y'], ys)
self.assertIn(plot.handles['vbar_1_glyph_renderer'], hover_tool.renderers)
self.assertIn(plot.handles['vbar_2_glyph_renderer'], hover_tool.renderers)
self.assertIn(plot.handles['circle_1_glyph_renderer'], hover_tool.renderers)
47 changes: 45 additions & 2 deletions tests/plotting/bokeh/testcallbacks.py
@@ -1,9 +1,14 @@
from collections import deque
from unittest import SkipTest

import numpy as np

from holoviews.core import DynamicMap
from holoviews.core.options import Store
from holoviews.element import Points, Polygons, Box
from holoviews.element import Points, Polygons, Box, Curve
from holoviews.element.comparison import ComparisonTestCase
from holoviews.streams import PointDraw, PolyDraw, PolyEdit, BoxEdit
from holoviews.streams import (PointDraw, PolyDraw, PolyEdit, BoxEdit,
PointerXY, PointerX)

try:
from bokeh.models import PolyEditTool
Expand All @@ -18,6 +23,44 @@
bokeh_renderer = None


class TestCallbacks(ComparisonTestCase):

def test_stream_callback(self):
dmap = DynamicMap(lambda x, y: Points([(x, y)]), kdims=[], streams=[PointerXY()])
plot = bokeh_renderer.get_plot(dmap)
bokeh_renderer(plot)
plot.callbacks[0].on_msg({"x": 10, "y": -10})
data = plot.handles['source'].data
self.assertEqual(data['x'], np.array([10]))
self.assertEqual(data['y'], np.array([-10]))

def test_stream_callback_with_ids(self):
dmap = DynamicMap(lambda x, y: Points([(x, y)]), kdims=[], streams=[PointerXY()])
plot = bokeh_renderer.get_plot(dmap)
bokeh_renderer(plot)
model = plot.state
plot.callbacks[0].on_msg({"x": {'id': model.ref['id'], 'value': 10},
"y": {'id': model.ref['id'], 'value': -10}})
data = plot.handles['source'].data
self.assertEqual(data['x'], np.array([10]))
self.assertEqual(data['y'], np.array([-10]))

def test_stream_callback_single_call(self):
def history_callback(x, history=deque(maxlen=10)):
history.append(x)
return Curve(list(history))
stream = PointerX(x=0)
dmap = DynamicMap(history_callback, kdims=[], streams=[stream])
plot = bokeh_renderer.get_plot(dmap)
bokeh_renderer(plot)
for i in range(20):
stream.event(x=i)
data = plot.handles['source'].data
self.assertEqual(data['x'], np.arange(10))
self.assertEqual(data['y'], np.arange(10, 20))



class TestEditToolCallbacks(ComparisonTestCase):

def setUp(self):
Expand Down

0 comments on commit 64ee6ec

Please sign in to comment.