Search code examples
holoviews

How do I set the scatter circle radius in holoviews?


Simple question - in bokeh you can plot circles with a radius rather than a size,such that the circles adjust when zooming in or out. Is it possible to do this with a holoviews based scatter - it doesn't have an option currently that I can see for setting the radius and I couldn't work out how to provide it in another manner (eg renders). Likely user error so apologies in advance, many thanks.

import holoviews as hv
hv.extension('bokeh')
from bokeh.plotting import figure, show
x=(1,2,3)
y=(1,2,3)
p=figure()
p.scatter(x, y, radius=0.2)
show(p) # bokeh plot working as expected
scatter=hv.Scatter((x,y)).opts(marker="circle", size=20)
scatter # holoviews plot, cannot code "radius" for code above - causes error.

Solution

  • All hv.Scatter plots are based around Bokeh's Scatter marker which has this section in its docstring:

    Note that circles drawn with `Scatter` conform to the standard Marker
    interface, and can only vary by size (in screen units) and *not* by radius
    (in data units). If you need to control circles by radius in data units,
    you should use the Circle glyph directly.
    

    This means that you cannot use hv.Scatter, you have to use something else:

    import holoviews as hv
    import param
    from holoviews.element.chart import Chart
    from holoviews.plotting.bokeh import PointPlot
    
    hv.extension('bokeh')
    
    x = (1, 2, 3)
    y = (1, 2, 3)
    
    
    class Circle(Chart):
        group = param.String(default='Circle', constant=True)
    
        size = param.Integer()
    
    
    class CirclePlot(PointPlot):
        _plot_methods = dict(single='circle', batched='circle')
    
        style_opts = ['radius' if so == 'size' else so for so in PointPlot.style_opts if so != 'marker']
    
    
    hv.Store.register({Circle: CirclePlot}, 'bokeh')
    
    scatter = Circle((x, y)).opts(radius=0.5)