Skip to content
Permalink
Browse files

Add `visible` style option for simple plotly/bokeh plots. (#3948)

* Add `visible` style opt for trace-based plotly plots.

Setting to False will fully hide the individual trace

* Add 'visible' style property to simple Bokeh elements
  • Loading branch information...
jonmmease authored and philippjfr committed Sep 10, 2019
1 parent 82acc56 commit a977c3daa405b35081910495382329a2d4ceef70
Showing with 161 additions and 46 deletions.
  1. +4 −4 holoviews/plotting/bokeh/annotation.py
  2. +16 −14 holoviews/plotting/bokeh/chart.py
  3. +1 −1 holoviews/plotting/bokeh/heatmap.py
  4. +1 −1 holoviews/plotting/bokeh/hex_tiles.py
  5. +2 −2 holoviews/plotting/bokeh/path.py
  6. +3 −3 holoviews/plotting/bokeh/raster.py
  7. +1 −1 holoviews/plotting/bokeh/tabular.py
  8. +1 −1 holoviews/plotting/plotly/annotation.py
  9. +17 −8 holoviews/plotting/plotly/chart.py
  10. +1 −1 holoviews/plotting/plotly/chart3d.py
  11. +5 −3 holoviews/plotting/plotly/element.py
  12. +1 −1 holoviews/plotting/plotly/raster.py
  13. +4 −4 holoviews/plotting/plotly/stats.py
  14. +1 −1 holoviews/plotting/plotly/tabular.py
  15. +5 −0 holoviews/tests/plotting/plotly/testareaplot.py
  16. +6 −1 holoviews/tests/plotting/plotly/testbarplot.py
  17. +5 −0 holoviews/tests/plotting/plotly/testbivariateplot.py
  18. +5 −0 holoviews/tests/plotting/plotly/testboxwhiskerplot.py
  19. +5 −0 holoviews/tests/plotting/plotly/testcurveplot.py
  20. +5 −0 holoviews/tests/plotting/plotly/testdistributionplot.py
  21. +8 −0 holoviews/tests/plotting/plotly/testerrorbarplot.py
  22. +5 −0 holoviews/tests/plotting/plotly/testhistogram.py
  23. +7 −0 holoviews/tests/plotting/plotly/testimageplot.py
  24. +5 −0 holoviews/tests/plotting/plotly/testlabelplot.py
  25. +5 −0 holoviews/tests/plotting/plotly/testpath3d.py
  26. +7 −0 holoviews/tests/plotting/plotly/testquadmeshplot.py
  27. +5 −0 holoviews/tests/plotting/plotly/testscatter3dplot.py
  28. +5 −0 holoviews/tests/plotting/plotly/testscatterplot.py
  29. +8 −0 holoviews/tests/plotting/plotly/testspreadplot.py
  30. +7 −0 holoviews/tests/plotting/plotly/testsurfaceplot.py
  31. +5 −0 holoviews/tests/plotting/plotly/testtableplot.py
  32. +5 −0 holoviews/tests/plotting/plotly/testviolinplot.py
@@ -28,7 +28,7 @@

class TextPlot(ElementPlot, AnnotationPlot):

style_opts = text_properties+['color', 'angle']
style_opts = text_properties+['color', 'angle', 'visible']
_plot_methods = dict(single='text', batched='text')

def get_data(self, element, ranges, style):
@@ -86,7 +86,7 @@ class LabelsPlot(ColorbarPlot, AnnotationPlot):
allow_None=True, doc="""
Deprecated in favor of color style mapping, e.g. `color=dim('color')`""")

style_opts = text_properties + ['cmap', 'angle']
style_opts = text_properties + ['cmap', 'angle', 'visible']

_nonvectorized_styles = ['cmap']

@@ -128,7 +128,7 @@ def get_data(self, element, ranges, style):

class LineAnnotationPlot(ElementPlot, AnnotationPlot):

style_opts = line_properties + ['level']
style_opts = line_properties + ['level', 'visible']

apply_ranges = param.Boolean(default=False, doc="""
Whether to include the annotation in axis range calculations.""")
@@ -174,7 +174,7 @@ class SplinePlot(ElementPlot, AnnotationPlot):
Does not support matplotlib Path codes.
"""

style_opts = line_properties
style_opts = line_properties + ['visible']
_plot_methods = dict(single='bezier')

def get_data(self, element, ranges, style):
@@ -52,7 +52,7 @@ class PointPlot(LegendPlot, ColorbarPlot):
Function applied to size values before applying scaling,
to remove values lower than zero.""")

style_opts = (['cmap', 'palette', 'marker', 'size', 'angle'] +
style_opts = (['cmap', 'palette', 'marker', 'size', 'angle', 'visible'] +
line_properties + fill_properties)

_plot_methods = dict(single='scatter', batched='scatter')
@@ -129,7 +129,7 @@ def get_batched_data(self, element, ranges):

# Angles need special handling since they are tied to the
# marker in certain cases
has_angles = False
has_angles = False
for (key, el), zorder in zip(element.data.items(), zorders):
self.param.set_param(**self.lookup_options(el, 'plot').options)
style = self.lookup_options(element.last, 'style')
@@ -211,9 +211,9 @@ class VectorFieldPlot(ColorbarPlot):
transforms using the magnitude option, e.g.
`dim('Magnitude').norm()`.""")

style_opts = line_properties + ['scale', 'cmap']
style_opts = line_properties + ['scale', 'cmap', 'visible']

_nonvectorized_styles = ['scale', 'cmap']
_nonvectorized_styles = ['scale', 'cmap', 'visible']

_plot_methods = dict(single='segment')

@@ -324,8 +324,8 @@ class CurvePlot(ElementPlot):
default is 'linear', other options include 'steps-mid',
'steps-pre' and 'steps-post'.""")

style_opts = line_properties
_nonvectorized_styles = line_properties
style_opts = line_properties + ['visible']
_nonvectorized_styles = line_properties + ['visible']

_plot_methods = dict(single='line', batched='multi_line')
_batched_style_opts = line_properties
@@ -391,10 +391,10 @@ def get_batched_data(self, overlay, ranges):

class HistogramPlot(ColorbarPlot):

style_opts = line_properties + fill_properties + ['cmap']
style_opts = line_properties + fill_properties + ['cmap', 'visible']
_plot_methods = dict(single='quad')

_nonvectorized_styles = ['line_dash']
_nonvectorized_styles = ['line_dash', 'visible']

def get_data(self, element, ranges, style):
if self.invert_axes:
@@ -497,9 +497,9 @@ def _init_glyph(self, plot, mapping, properties):

class ErrorPlot(ColorbarPlot):

style_opts = line_properties + ['lower_head', 'upper_head']
style_opts = line_properties + ['lower_head', 'upper_head', 'visible']

_nonvectorized_styles = ['line_dash']
_nonvectorized_styles = ['line_dash', 'visible']

_mapping = dict(base="base", upper="upper", lower="lower")

@@ -553,7 +553,7 @@ def _init_glyph(self, plot, mapping, properties):

class SpreadPlot(ElementPlot):

style_opts = line_properties + fill_properties
style_opts = line_properties + fill_properties + ['visible']
_no_op_style = style_opts

_plot_methods = dict(single='patch')
@@ -659,7 +659,7 @@ class SpikesPlot(ColorbarPlot):
allow_None=True, doc="""
Deprecated in favor of color style mapping, e.g. `color=dim('color')`""")

style_opts = (['color', 'cmap', 'palette'] + line_properties)
style_opts = (['color', 'cmap', 'palette', 'visible'] + line_properties)

_plot_methods = dict(single='segment')

@@ -767,9 +767,11 @@ class BarPlot(ColorbarPlot, LegendPlot):
allow_None=True, doc="""
Deprecated; use stacked option instead.""")

style_opts = line_properties + fill_properties + ['width', 'bar_width', 'cmap']
style_opts = (line_properties
+ fill_properties
+ ['width', 'bar_width', 'cmap', 'visible'])

_nonvectorized_styles = ['bar_width', 'cmap', 'width']
_nonvectorized_styles = ['bar_width', 'cmap', 'width', 'visible']

_plot_methods = dict(single=('vbar', 'hbar'))

@@ -52,7 +52,7 @@ class HeatMapPlot(ColorbarPlot):

style_opts = (['xmarks_' + p for p in line_properties] +
['ymarks_' + p for p in line_properties] +
['cmap', 'color', 'dilate'] + line_properties + fill_properties)
['cmap', 'color', 'dilate', 'visible'] + line_properties + fill_properties)

_categorical = True

@@ -138,7 +138,7 @@ class HexTilesPlot(ColorbarPlot):

_plot_methods = dict(single='hex_tile')

style_opts = ['cmap', 'color', 'scale'] + line_properties + fill_properties
style_opts = ['cmap', 'color', 'scale', 'visible'] + line_properties + fill_properties

_nonvectorized_styles = ['cmap', 'line_dash']

@@ -26,7 +26,7 @@ class PathPlot(LegendPlot, ColorbarPlot):
allow_None=True, doc="""
Deprecated in favor of color style mapping, e.g. `color=dim('color')`""")

style_opts = line_properties + ['cmap']
style_opts = line_properties + ['cmap', 'visible']
_plot_methods = dict(single='multi_line', batched='multi_line')
_mapping = dict(xs='xs', ys='ys')
_batched_style_opts = line_properties
@@ -270,7 +270,7 @@ def _init_glyph(self, plot, mapping, properties):

class PolygonPlot(ContourPlot):

style_opts = ['cmap'] + line_properties + fill_properties
style_opts = ['cmap', 'visible'] + line_properties + fill_properties
_plot_methods = dict(single='patches', batched='patches')
_batched_style_opts = line_properties + fill_properties
_color_style = 'fill_color'
@@ -19,7 +19,7 @@ class RasterPlot(ColorbarPlot):
show_legend = param.Boolean(default=False, doc="""
Whether to show legend for the plot.""")

style_opts = ['cmap', 'alpha']
style_opts = ['cmap', 'alpha', 'visible']

_nonvectorized_styles = style_opts

@@ -120,7 +120,7 @@ def get_data(self, element, ranges, style):

class RGBPlot(ElementPlot):

style_opts = ['alpha']
style_opts = ['alpha', 'visible']

_nonvectorized_styles = style_opts

@@ -194,7 +194,7 @@ class QuadMeshPlot(ColorbarPlot):
show_legend = param.Boolean(default=False, doc="""
Whether to show legend for the plot.""")

style_opts = ['cmap', 'color'] + line_properties + fill_properties
style_opts = ['cmap', 'color', 'visible'] + line_properties + fill_properties

_nonvectorized_styles = style_opts

@@ -32,7 +32,7 @@ class TablePlot(BokehPlot, GenericElementPlot):

style_opts = ['row_headers', 'selectable', 'editable',
'sortable', 'fit_columns', 'scroll_to_selection',
'index_position']
'index_position', 'visible']

_stream_data = True

@@ -13,7 +13,7 @@ class LabelPlot(ScatterPlot):
yoffset = param.Number(default=None, doc="""
Amount of offset to apply to labels along x-axis.""")

style_opts = ['color', 'family', 'size']
style_opts = ['visible', 'color', 'family', 'size']

_nonvectorized_styles = []

@@ -28,10 +28,17 @@ class ScatterPlot(ChartPlot, ColorbarPlot):
Index of the dimension from which the color will the drawn""")

style_opts = [
'marker', 'color', 'cmap', 'alpha', 'size', 'sizemin', 'selectedpoints'
'visible',
'marker',
'color',
'cmap',
'alpha',
'size',
'sizemin',
'selectedpoints',
]

_nonvectorized_styles = ['cmap', 'alpha', 'sizemin', 'selectedpoints']
_nonvectorized_styles = ['visible', 'cmap', 'alpha', 'sizemin', 'selectedpoints']

trace_kwargs = {'type': 'scatter', 'mode': 'markers'}

@@ -62,7 +69,7 @@ class CurvePlot(ChartPlot, ColorbarPlot):

trace_kwargs = {'type': 'scatter', 'mode': 'lines'}

style_opts = ['color', 'dash', 'line_width']
style_opts = ['visible', 'color', 'dash', 'line_width']

_nonvectorized_styles = style_opts

@@ -76,7 +83,7 @@ def get_data(self, element, ranges, style):

class AreaPlot(ChartPlot):

style_opts = ['color', 'dash', 'line_width']
style_opts = ['visible', 'color', 'dash', 'line_width']

trace_kwargs = {'type': 'scatter', 'mode': 'lines'}

@@ -112,7 +119,7 @@ def get_data(self, element, ranges, style):

class SpreadPlot(ChartPlot):

style_opts = ['color', 'dash', 'line_width']
style_opts = ['visible', 'color', 'dash', 'line_width']

trace_kwargs = {'type': 'scatter', 'mode': 'lines'}

@@ -129,13 +136,13 @@ def get_data(self, element, ranges, style):
upper = mean + pos_error
return [{x: xs, y: lower, 'fill': None},
{x: xs, y: upper, 'fill': 'tonext'+y}]


class ErrorBarsPlot(ChartPlot, ColorbarPlot):

trace_kwargs = {'type': 'scatter', 'mode': 'lines', 'line': {'width': 0}}

style_opts = ['color', 'dash', 'line_width', 'thickness']
style_opts = ['visible', 'color', 'dash', 'line_width', 'thickness']

_nonvectorized_styles = style_opts

@@ -176,6 +183,8 @@ class BarPlot(ElementPlot):

stacked = param.Boolean(default=False)

style_opts = ['visible']

trace_kwargs = {'type': 'bar'}

def get_extents(self, element, ranges, range_type='combined'):
@@ -287,7 +296,7 @@ class HistogramPlot(ElementPlot):

trace_kwargs = {'type': 'bar'}

style_opts = ['color', 'line_color', 'line_width', 'opacity']
style_opts = ['visible', 'color', 'line_color', 'line_width', 'opacity']

_style_key = 'marker'

@@ -41,7 +41,7 @@ class SurfacePlot(Chart3DPlot, ColorbarPlot):

trace_kwargs = {'type': 'surface'}

style_opts = ['alpha', 'lighting', 'lightposition', 'cmap']
style_opts = ['visible', 'alpha', 'lighting', 'lightposition', 'cmap']

def graph_options(self, element, ranges, style):
opts = super(SurfacePlot, self).graph_options(element, ranges, style)
@@ -213,9 +213,11 @@ def graph_options(self, element, ranges, style):
opts[self._style_key] = {STYLE_ALIASES.get(k, k): v
for k, v in styles.items()}

# Move selectedpoints from style key back to root
if 'selectedpoints' in opts.get(self._style_key, {}):
opts['selectedpoints'] = opts[self._style_key].pop('selectedpoints')
# Move certain options from the style key back to root
for k in ['selectedpoints', 'visible']:
if k in opts.get(self._style_key, {}):
opts[k] = opts[self._style_key].pop(k)

else:
opts.update({STYLE_ALIASES.get(k, k): v
for k, v in style.items() if k != 'cmap'})
@@ -9,7 +9,7 @@

class RasterPlot(ColorbarPlot):

style_opts = ['cmap', 'alpha']
style_opts = ['visible', 'cmap', 'alpha']

trace_kwargs = {'type': 'heatmap'}

@@ -14,7 +14,7 @@ class BivariatePlot(ChartPlot, ColorbarPlot):

trace_kwargs = {'type': 'histogram2dcontour'}

style_opts = ['cmap', 'showlabels', 'labelfont', 'labelformat', 'showlines']
style_opts = ['visible', 'cmap', 'showlabels', 'labelfont', 'labelformat', 'showlines']

_style_key = 'contours'

@@ -58,7 +58,7 @@ class DistributionPlot(ElementPlot):
filled = param.Boolean(default=True, doc="""
Whether the bivariate contours should be filled.""")

style_opts = ['color', 'dash', 'line_width']
style_opts = ['visible', 'color', 'dash', 'line_width']

trace_kwargs = {'type': 'scatter', 'mode': 'lines'}

@@ -112,7 +112,7 @@ class BoxWhiskerPlot(MultiDistributionPlot):
is drawn as a dashed line inside the box(es). If "sd" the
standard deviation is also drawn.""")

style_opts = ['color', 'alpha', 'outliercolor', 'marker', 'size']
style_opts = ['visible', 'color', 'alpha', 'outliercolor', 'marker', 'size']

trace_kwargs = {'type': 'box'}

@@ -136,7 +136,7 @@ class ViolinPlot(MultiDistributionPlot):
is drawn as a dashed line inside the box(es). If "sd" the
standard deviation is also drawn.""")

style_opts = ['color', 'alpha', 'outliercolor', 'marker', 'size']
style_opts = ['visible', 'color', 'alpha', 'outliercolor', 'marker', 'size']

trace_kwargs = {'type': 'violin'}

@@ -13,7 +13,7 @@ class TablePlot(ElementPlot):

trace_kwargs = {'type': 'table'}

style_opts = ['line', 'fill', 'align', 'font', 'cell_height']
style_opts = ['visible', 'line', 'fill', 'align', 'font', 'cell_height']

_style_key = 'cells'

@@ -50,3 +50,8 @@ def test_area_fill_between_xs(self):
self.assertEqual(state['data'][1]['fill'], 'tonextx')
self.assertEqual(state['layout']['xaxis']['range'], [0.5, 3])
self.assertEqual(state['layout']['yaxis']['range'], [0, 2])

def test_area_visible(self):
curve = Area([1, 2, 3]).options(visible=False)
state = self._get_plot_state(curve)
self.assertEqual(state['data'][0]['visible'], False)

0 comments on commit a977c3d

Please sign in to comment.
You can’t perform that action at this time.