Ejemplo n.º 1
0
    def test_handle_message_ready_reply(self):
        def assert_ready(msg=None, metadata=None):
            self.assertEqual(metadata, {'msg_type': "Ready", 'content': ''})

        comm = Comm(id='Test')
        comm.send = assert_ready
        comm._handle_msg({})
Ejemplo n.º 2
0
 def test_handle_message_ready_reply_with_comm_id(self):
     def assert_ready(msg=None, metadata=None):
         self.assertEqual(metadata, {'msg_type': "Ready", 'content': '',
                                     'comm_id': 'Testing id'})
     comm = Comm(id='Test')
     comm.send = assert_ready
     comm._handle_msg({'comm_id': 'Testing id'})
Ejemplo n.º 3
0
 def test_handle_message_error_reply(self):
     def raise_error(msg=None, metadata=None):
         raise Exception('Test')
     def assert_error(msg=None, metadata=None):
         self.assertEqual(metadata['msg_type'], "Error")
         self.assertTrue(metadata['traceback'].endswith('Exception: Test'))
     comm = Comm(id='Test', on_msg=raise_error)
     comm.send = assert_error
     comm._handle_msg({})
Ejemplo n.º 4
0
 def test_handle_message_error_reply(self):
     def raise_error(msg=None, metadata=None):
         raise Exception('Test')
     def assert_error(msg=None, metadata=None):
         self.assertEqual(metadata['msg_type'], "Error")
         self.assertTrue(metadata['traceback'].endswith('Exception: Test'))
     comm = Comm(id='Test', on_msg=raise_error)
     comm.send = assert_error
     comm._handle_msg({})
Ejemplo n.º 5
0
    def test_handle_message_ready_reply(self):
        def assert_ready(msg):
            self.assertEqual(json.loads(msg), {
                'msg_type': "Ready",
                'content': ''
            })

        comm = Comm(id='Test')
        comm.send = assert_ready
        comm._handle_msg({})
Ejemplo n.º 6
0
    def test_handle_message_ready_reply_with_comm_id(self):
        def assert_ready(msg):
            decoded = json.loads(msg)
            self.assertEqual(decoded, {
                'msg_type': "Ready",
                'content': '',
                'comm_id': 'Testing id'
            })

        comm = Comm(id='Test')
        comm.send = assert_ready
        comm._handle_msg({'comm_id': 'Testing id'})
Ejemplo n.º 7
0
    def test_handle_message_error_reply(self):
        def raise_error(msg):
            raise Exception('Test')

        def assert_error(msg):
            decoded = json.loads(msg)
            self.assertEqual(decoded['msg_type'], "Error")
            self.assertTrue(decoded['traceback'].endswith('Exception: Test'))

        comm = Comm(id='Test', on_msg=raise_error)
        comm.send = assert_error
        comm._handle_msg({})
Ejemplo n.º 8
0
def show_embed(panel, max_states=1000, max_opts=3, json=False,
              save_path='./', load_path=None):
    """
    Renders a static version of a panel in a notebook by evaluating
    the set of states defined by the widgets in the model. Note
    this will only work well for simple apps with a relatively
    small state space.

    Arguments
    ---------
    max_states: int
      The maximum number of states to embed
    max_opts: int
      The maximum number of states for a single widget
    json: boolean (default=True)
      Whether to export the data to json files
    save_path: str (default='./')
      The path to save json files to
    load_path: str (default=None)
      The path or URL the json files will be loaded from.
    """
    from IPython.display import publish_display_data
    from ..config import config

    doc = Document()
    comm = Comm()
    with config.set(embed=True):
        model = panel.get_root(doc, comm)
        embed_state(panel, model, doc, max_states, max_opts,
                    json, save_path, load_path)
    publish_display_data(*render_model(model))
Ejemplo n.º 9
0
def test_point_annotator_updates():
    annot = PointAnnotator(point_columns=['Size'], points=sample_points)
    panel = annot.panel()
    root_model = panel.get_root(
        comm=Comm())  # Pass comm to ensure update is applied

    updated_points = dict(sample_points, Size=sample_points['Size'][::-1])
    points = Points(updated_points, vdims=['Size'], crs=ccrs.GOOGLE_MERCATOR)
    annot.points = points

    fig = root_model.select_one({'type': Plot})
    points = fig.renderers[-1]
    table = root_model.select_one({'type': DataTable})

    # Ensure points data matches
    for k in updated_points:
        np.testing.assert_allclose(points.data_source.data[k],
                                   updated_points[k])

    # Ensure point is linked to table
    point_cbs = points.data_source.js_property_callbacks['change:data']
    assert sum([
        cb.code == PointTableLinkCallback.source_code for cb in point_cbs
    ]) == 1

    table_cbs = table.source.js_property_callbacks['change:data']
    assert len(table_cbs) == 1
    assert table_cbs[0].code == PointTableLinkCallback.target_code
Ejemplo n.º 10
0
    def test_update_dynamic_map_with_stream(self):
        ys = np.arange(10)

        # Build stream
        Scale = Stream.define('Scale', scale=1.0)
        scale_stream = Scale()

        # Build DynamicMap
        def build_scatter(scale):
            return hv.Scatter(ys * scale)

        dmap = hv.DynamicMap(build_scatter, streams=[scale_stream])

        # Create HoloViews Pane using panel so that we can access the plotly pane
        # used to display the plotly figure
        dmap_pane = pn.pane.HoloViews(dmap, backend='plotly')

        # Call get_root to force instantiation of internal plots/models
        doc = Document()
        comm = Comm()
        dmap_pane.get_root(doc, comm)

        # Get reference to the plotly pane
        _, plotly_pane = next(iter(dmap_pane._plots.values()))

        # Check initial data
        data = plotly_pane.object['data']
        self.assertEqual(len(data), 1)
        self.assertEqual(data[0]['type'], 'scatter')
        np.testing.assert_equal(data[0]['y'], ys)

        # Watch object for changes
        fn = Mock()
        plotly_pane.param.watch(fn, 'object')

        # Update stream
        scale_stream.event(scale=2.0)

        # Check that figure object was updated
        data = plotly_pane.object['data']
        np.testing.assert_equal(data[0]['y'], ys * 2.0)

        # Check that object callback was triggered
        fn.assert_called_once()
        args, kwargs = fn.call_args_list[0]
        event = args[0]
        self.assertIs(event.obj, plotly_pane)
        self.assertIs(event.new, plotly_pane.object)
Ejemplo n.º 11
0
def test_poly_annotator_update_models():
    annot = PolyAnnotator(poly_columns=['Group'],
                          polys=[sample_poly],
                          vertex_columns=['Weight'])
    panel = annot.panel()
    root_model = panel.get_root(
        comm=Comm())  # Pass comm to ensure update is applied

    poly = Polygons([dict(sample_poly, Test=1)],
                    vdims=['Test'],
                    crs=ccrs.GOOGLE_MERCATOR)
    annot.poly_columns = ['Test']
    annot.polys = poly

    fig = root_model.select_one({'type': Plot})
    polys = fig.renderers[1]
    table1, table2 = root_model.select({'type': DataTable})
    if 'xs' in table1.source.data:
        table1, table2 = table2, table1  # Ensure tables are correctly ordered

    # Ensure poly data matches
    np.testing.assert_allclose(polys.data_source.data['xs'][0][:-1],
                               sample_poly['Longitude'])
    np.testing.assert_allclose(polys.data_source.data['ys'][0][:-1],
                               sample_poly['Latitude'])
    np.testing.assert_allclose(polys.data_source.data['Test'][0], np.ones(6))

    # Ensure table and poly data are linked
    assert table2.source is polys.data_source

    # Ensure poly is linked to vertex table
    poly_cbs = polys.data_source.js_property_callbacks['change:data']
    assert sum([
        cb.code == VertexTableLinkCallback.source_code for cb in poly_cbs
    ]) == 1

    table_cbs = table1.source.js_property_callbacks['change:data']
    assert len(table_cbs) == 1
    assert table_cbs[0].code == VertexTableLinkCallback.target_code
Ejemplo n.º 12
0
 def test_decode(self):
     msg = 'Test'
     self.assertEqual(Comm.decode(msg), msg)
Ejemplo n.º 13
0
    def test_interactive_streams(self):
        ys = np.arange(10)
        scatter1 = hv.Scatter(ys)
        scatter2 = hv.Scatter(ys)
        scatter3 = hv.Scatter(ys)

        # Single stream on the first scatter
        rangexy1 = RangeXY(source=scatter1)

        # Multiple streams of the same type on second scatter
        boundsxy2a = BoundsXY(source=scatter2)
        boundsxy2b = BoundsXY(source=scatter2)

        # Multiple streams of different types on third scatter
        rangexy3 = RangeXY(source=scatter3)
        boundsxy3 = BoundsXY(source=scatter3)
        selection1d3 = Selection1D(source=scatter3)

        # Build layout and layout Pane
        layout = scatter1 + scatter2 + scatter3
        layout_pane = pn.pane.HoloViews(layout, backend='plotly')

        # Get plotly pane reference
        doc = Document()
        comm = Comm()
        layout_pane.get_root(doc, comm)
        _, plotly_pane = next(iter(layout_pane._plots.values()))

        # Simulate zoom and check that RangeXY streams updated accordingly
        plotly_pane.viewport = {
            'xaxis.range': [1, 3],
            'yaxis.range': [2, 4],
            'xaxis2.range': [3, 5],
            'yaxis2.range': [4, 6],
            'xaxis3.range': [5, 7],
            'yaxis3.range': [6, 8],
        }

        self.assertEqual(rangexy1.x_range, (1, 3))
        self.assertEqual(rangexy1.y_range, (2, 4))
        self.assertEqual(rangexy3.x_range, (5, 7))
        self.assertEqual(rangexy3.y_range, (6, 8))

        plotly_pane.viewport = None
        self.assertIsNone(rangexy1.x_range)
        self.assertIsNone(rangexy1.y_range)
        self.assertIsNone(rangexy3.x_range)
        self.assertIsNone(rangexy3.y_range)

        # Simulate box selection and check that BoundsXY and Selection1D streams
        # update accordingly

        # Box select on second subplot
        plotly_pane.selected_data = {
            'points': [],
            'range': {
                'x2': [10, 20],
                'y2': [11, 22]
            }
        }

        self.assertEqual(boundsxy2a.bounds, (10, 11, 20, 22))
        self.assertEqual(boundsxy2b.bounds, (10, 11, 20, 22))

        # Box selecrt on third subplot
        plotly_pane.selected_data = {
            'points': [
                {'curveNumber': 2, 'pointNumber': 0},
                {'curveNumber': 2, 'pointNumber': 3},
                {'curveNumber': 2, 'pointNumber': 7},
            ],
            'range': {
                'x3': [0, 5],
                'y3': [1, 6]
            }
        }

        self.assertEqual(boundsxy3.bounds, (0, 1, 5, 6))
        self.assertEqual(selection1d3.index, [0, 3, 7])

        # bounds streams on scatter 2 are None
        self.assertIsNone(boundsxy2a.bounds)
        self.assertIsNone(boundsxy2b.bounds)

        # Clear selection
        plotly_pane.selected_data = None
        self.assertIsNone(boundsxy3.bounds)
        self.assertIsNone(boundsxy2a.bounds)
        self.assertIsNone(boundsxy2b.bounds)
        self.assertEqual(selection1d3.index, [])
Ejemplo n.º 14
0
def save(panel,
         filename,
         title=None,
         resources=None,
         template=None,
         template_variables=None,
         embed=False,
         max_states=1000,
         max_opts=3,
         embed_json=False,
         json_prefix='',
         save_path='./',
         load_path=None,
         progress=True):
    """
    Saves Panel objects to file.

    Arguments
    ---------
    panel: Viewable
      The Panel Viewable to save to file
    filename: string or file-like object
      Filename to save the plot to
    title: string
      Optional title for the plot
    resources: bokeh resources
      One of the valid bokeh.resources (e.g. CDN or INLINE)
    template:
      template file, as used by bokeh.file_html. If None will use bokeh defaults
    template_variables:
      template_variables file dict, as used by bokeh.file_html
    embed: bool
      Whether the state space should be embedded in the saved file.
    max_states: int
      The maximum number of states to embed
    max_opts: int
      The maximum number of states for a single widget
    embed_json: boolean (default=True)
      Whether to export the data to json files
    json_prefix: str (default='')
      Prefix for the randomly json directory
    save_path: str (default='./')
      The path to save json files to
    load_path: str (default=None)
      The path or URL the json files will be loaded from.
    progress: boolean (default=True)
      Whether to report progress
    """
    from ..pane import PaneBase

    if isinstance(panel, PaneBase) and len(panel.layout) > 1:
        panel = panel.layout

    as_png = isinstance(filename, string_types) and filename.endswith('png')

    doc = Document()
    comm = Comm()
    with config.set(embed=embed):
        with swap_html_model(as_png):
            model = panel.get_root(doc, comm)
        if embed:
            embed_state(panel, model, doc, max_states, max_opts, embed_json,
                        json_prefix, save_path, load_path, progress)
        else:
            add_to_doc(model, doc, True)

    if as_png:
        save_png(model, filename=filename)
        return
    elif isinstance(filename, string_types) and not filename.endswith('.html'):
        filename = filename + '.html'

    kwargs = {}
    if title is None:
        title = 'Panel'
    if resources is None:
        resources = CDN
    if template:
        kwargs['template'] = template
    if template_variables:
        kwargs['template_variables'] = template_variables

    html = file_html(doc, resources, title, **kwargs)
    if hasattr(filename, 'write'):
        html = decode_utf8(html)
        if isinstance(filename, io.BytesIO):
            html = html.encode('utf-8')
        filename.write(html)
        return
    with io.open(filename, mode="w", encoding="utf-8") as f:
        f.write(decode_utf8(html))
Ejemplo n.º 15
0
def save(panel,
         filename,
         title=None,
         resources=None,
         template=None,
         template_variables={},
         embed=False,
         max_states=1000,
         max_opts=3,
         embed_json=False,
         save_path='./',
         load_path=None):
    """
    Saves Panel objects to file.

    Arguments
    ---------
    panel: Viewable
      The Panel Viewable to save to file
    filename: string or file-like object
      Filename to save the plot to
    title: string
      Optional title for the plot
    resources: bokeh resources
      One of the valid bokeh.resources (e.g. CDN or INLINE)
    embed: bool
      Whether the state space should be embedded in the saved file.
    max_states: int
      The maximum number of states to embed
    max_opts: int
      The maximum number of states for a single widget
    embed_json: boolean (default=True)
      Whether to export the data to json files
    save_path: str (default='./')
      The path to save json files to
    load_path: str (default=None)
      The path or URL the json files will be loaded from.
    """
    doc = Document()
    comm = Comm()
    with config.set(embed=embed):
        model = panel.get_root(doc, comm)
        if embed:
            embed_state(panel, model, doc, max_states, max_opts, embed_json,
                        save_path, load_path)
        else:
            add_to_doc(model, doc, True)

    if isinstance(filename, string_types):
        if filename.endswith('png'):
            save_png(model, filename=filename)
            return
        if not filename.endswith('.html'):
            filename = filename + '.html'

    kwargs = {}
    if title is None:
        title = 'Panel'
    if resources is None:
        resources = CDN
    if template:
        kwargs['template'] = template

    html = file_html(doc, resources, title, **kwargs)
    if hasattr(filename, 'write'):
        filename.write(decode_utf8(html))
        return
    with io.open(filename, mode="w", encoding="utf-8") as f:
        f.write(decode_utf8(html))
Ejemplo n.º 16
0
 def test_init_comm(self):
     Comm()
Ejemplo n.º 17
0
 def test_init_comm_id(self):
     comm = Comm(id='Test')
     self.assertEqual(comm.id, 'Test')
Ejemplo n.º 18
0
def save(panel,
         filename,
         title=None,
         resources=None,
         template=None,
         template_variables=None,
         embed=False,
         max_states=1000,
         max_opts=3,
         embed_json=False,
         json_prefix='',
         save_path='./',
         load_path=None,
         progress=True,
         embed_states={},
         as_png=None,
         **kwargs):
    """
    Saves Panel objects to file.

    Arguments
    ---------
    panel: Viewable
      The Panel Viewable to save to file
    filename: string or file-like object
      Filename to save the plot to
    title: string
      Optional title for the plot
    resources: bokeh resources
      One of the valid bokeh.resources (e.g. CDN or INLINE)
    template:
      template file, as used by bokeh.file_html. If None will use bokeh defaults
    template_variables:
      template_variables file dict, as used by bokeh.file_html
    embed: bool
      Whether the state space should be embedded in the saved file.
    max_states: int
      The maximum number of states to embed
    max_opts: int
      The maximum number of states for a single widget
    embed_json: boolean (default=True)
      Whether to export the data to json files
    json_prefix: str (default='')
      Prefix for the randomly json directory
    save_path: str (default='./')
      The path to save json files to
    load_path: str (default=None)
      The path or URL the json files will be loaded from.
    progress: boolean (default=True)
      Whether to report progress
    embed_states: dict (default={})
      A dictionary specifying the widget values to embed for each widget
    save_png: boolean (default=None)
        To save as a .png. If None save_png will be true if filename is
        string and ends with png.
    """
    from ..pane import PaneBase
    from ..template import BaseTemplate

    if isinstance(panel, PaneBase) and len(panel.layout) > 1:
        panel = panel.layout

    if as_png is None:
        as_png = isinstance(filename, str) and filename.endswith('png')

    if isinstance(panel, Document):
        doc = panel
    else:
        doc = Document()

    if resources is None:
        resources = CDN
        mode = 'cdn'
    elif isinstance(resources, str):
        if resources.lower() == 'cdn':
            resources = CDN
            mode = 'cdn'
        elif resources.lower() == 'inline':
            resources = INLINE
            mode = 'inline'
        else:
            raise ValueError("Resources %r not recognized, specify one "
                             "of 'CDN' or 'INLINE'." % resources)
    elif isinstance(resources, BkResources):
        mode = resources.mode

    comm = Comm()
    with config.set(embed=embed):
        if isinstance(panel, Document):
            model = panel
        elif isinstance(panel, BaseTemplate):
            with set_resource_mode(mode):
                panel._init_doc(doc, title=title)
            model = doc
        else:
            model = panel.get_root(doc, comm)
            if embed:
                embed_state(panel, model, doc, max_states, max_opts,
                            embed_json, json_prefix, save_path, load_path,
                            progress, embed_states)
            else:
                add_to_doc(model, doc, True)

    if as_png:
        return save_png(model,
                        resources=resources,
                        filename=filename,
                        template=template,
                        template_variables=template_variables,
                        **kwargs)
    elif isinstance(filename, str) and not filename.endswith('.html'):
        filename = filename + '.html'

    kwargs = {}
    if title is None:
        title = 'Panel'

    if template:
        kwargs['template'] = template
    if template_variables:
        kwargs['template_variables'] = template_variables

    resources = Resources.from_bokeh(resources, absolute=True)

    # Set resource mode
    with set_resource_mode(resources):
        html = file_html(doc, resources, title, **kwargs)
    if hasattr(filename, 'write'):
        if isinstance(filename, io.BytesIO):
            html = html.encode('utf-8')
        filename.write(html)
    else:
        with io.open(filename, mode="w", encoding="utf-8") as f:
            f.write(html)
Ejemplo n.º 19
0
def comm():
    return Comm()
Ejemplo n.º 20
0
 def test_decode(self):
     msg = 'Test'
     self.assertEqual(Comm.decode(msg), msg)