# How to create a custom HoloViews plotting backend

**URL:** <https://discourse.holoviz.org/t/how-to-create-a-custom-holoviews-plotting-backend/7555>\
**Category:** HoloViews\
**Tags:** holoviews\
**Created:** [August 8, 2024, 7:00pm UTC](https://discourse.holoviz.org/t/how-to-create-a-custom-holoviews-plotting-backend/7555 "2024-08-08T19:00:55Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![ahuang11](https://discourse.holoviz.org/user_avatar/discourse.holoviz.org/ahuang11/32/4947_2.png) [@ahuang11](https://discourse.holoviz.org/u/ahuang11)\
**Post date:** [August 8, 2024, 7:00pm UTC](https://discourse.holoviz.org/t/how-to-create-a-custom-holoviews-plotting-backend/7555/1 "2024-08-08T19:00:55Z")

</div>

Taken from Philipp

 ![image](https://discourse.holoviz.org/uploads/default/original/2X/9/9de9795b792b67da73b04186cb651b976570a985.png)

> **[Discord - Group Chat That’s All Fun & Games](https://discord.com/channels/1075331058024861767/1101491607758450800/1271098770519625783)**
>
> Discord is great for playing games and chilling with friends, or even building a worldwide community. Customize your own space to talk, play, and hang out.

```python
import holoviews as hv
import panel as pn
import param

from holoviews.plotting.plot import GenericElementPlot, DimensionedPlot, CallbackPlot
from holoviews.plotting.renderer import Renderer

class VegaRenderer(Renderer):

    backend = param.String(default='vega', doc="The backend name.")

    
    mode_formats = {'fig': ['html',],
                    'holomap': ['widgets', 'scrubber', 'gif', 'auto']}
    
    _render_with_panel = True

    @classmethod
    def load_nb(cls, inline=True):
        """
        Loads the plotly notebook resources.
        """
        import panel.models.vega # noqa
        cls._loaded = True
        if 'vega' not in getattr(pn.extension, '_loaded_extensions', ['vega']):
            pn.extension._loaded_extensions.append('vega')

    @classmethod
    def plot_options(cls, obj, percent_size):
        return {}

    
    def _figure_data(self, plot, fmt, as_script=False, **kwargs):
        return plot.handles['fig']

class VegaPlot(DimensionedPlot, CallbackPlot):

    backend = 'vega'

    def initialize_plot(self, ranges=None, is_geo=False):
        return self.generate_plot(self.keys[-1], ranges, is_geo=is_geo)

    def update_frame(self, key, ranges=None, is_geo=False):
        return self.generate_plot(key, ranges, is_geo=is_geo)
    
    @property
    def state(self):
        """
        The plotting state that gets updated via the update method and
        used by the renderer to generate output.
        """
        return self.handles['fig']

class CurvePlot(VegaPlot, GenericElementPlot):

    def generate_plot(self, key, ranges, element=None, is_geo=False):
        if element is None:
            element = self._get_frame(key)
        else:
            self.current_frame = element

        xdim, ydim = element.dimensions()[:2]
        
        self.handles['fig'] = fig = {
          "data": {"values": element.dframe()},
          "mark": "line",
          "encoding": {
            "x": {"field": xdim.name, "type": "quantitative"},
            "y": {"field": ydim.name, "type": "quantitative"}
          },
            "$schema": "https://vega.github.io/schema/vega-lite/v3.2.1.json"
        }
        return fig
        

pn.pane.HoloViews.param.backend.objects.append('vega')
pn.pane.HoloViews._panes['vega'] = pn.pane.Vega

hv.Store.renderers['vega'] = VegaRenderer.instance()
hv.Store.register({hv.Curve: CurvePlot}, backend='vega')

# Needs a fix in hv.util. __init__.py
# hv.extension._backends['vega'] = 'vega'

hv.extension('vega')
hv.Store.current_backend = 'vega'

# Need another fix in the HoloViews pane

hv.Curve([1, 2, 3])

```
