We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Vega plot not displaying within a holoviz panel in jupyter notebook
Apparently, vega plots have issues being shown when within a panel in a jupyter notebook. This might have something to do with Panel not serialising the data correctly.

For a minimal script showing the issue, see at the bottom of this question.

My findings:

* The vega import works nicely when used outside of a panel: the Vega specification copy/pasted from https://vega.github.io/editor/#/examples/vega/force-directed-layout is visualised as it should be using  `Vega(spec)`.
* When using  `pn.pane.Vega(spec)`  I get an empty space. Running the visualisation externally using  `pn.pane.Vega(spec).show()`  and looking at the source code, I see that the div is empty.

Versions:

* panel 0.7.0
* bokeh 1.4.0
* vega 2.6.0
* jupyter 1.0.0


```
#!/usr/bin/env python
import panel as pn
from bokeh.plotting import figure, output_notebook, show
from vega import VegaLite, Vega
pn.extension()
pn.extension('vega')
output_notebook()

spec = {
  "$schema": "https://vega.github.io/schema/vega/v5.json",
  "width": 400,
  "height": 200,

  "data": [
    {
      "name": "table",
      "values": [
        {"category": "A", "amount": 28},
        {"category": "B", "amount": 55},
        {"category": "C", "amount": 43}
      ]
    }
  ],

  "scales": [
    {
      "name": "xscale",
      "type": "band",
      "domain": {"data": "table", "field": "category"},
      "range": "width"
    },
    {
      "name": "yscale",
      "domain": {"data": "table", "field": "amount"},
      "range": "height"
    }
  ],

  "marks": [
    {
      "type": "rect",
      "from": {"data":"table"},
      "encode": {
        "enter": {
          "x": {"scale": "xscale", "field": "category"},
          "width": {"scale": "xscale", "band": 1},
          "y": {"scale": "yscale", "field": "amount"},
          "y2": {"scale": "yscale", "value": 0}
        },
        "update": {
          "fill": {"value": "steelblue"}
        }
      }
    }
  ]
}

Vega(spec) # => shows barchart => OK

pn.Column(pn.panel("## Vega test"),
          pn.pane.Vega(spec),
          pn.panel("_end of test_"))
# => shows "Vega test", then empty space, the "end of test"

pn.Column(pn.panel("## Vega test"),
          pn.panel(spec),
          pn.panel("_end of test_"))
# => shows "Vega test", then empty space, the "end of test"
```

Thank you,
jan.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `panel/pane/vega.py`
Content:
```
1 from __future__ import absolute_import, division, unicode_literals
2 
3 import sys
4 
5 import param
6 import numpy as np
7 
8 from bokeh.models import ColumnDataSource
9 from pyviz_comms import JupyterComm
10 
11 from ..viewable import Layoutable
12 from .base import PaneBase
13 
14 
15 def ds_as_cds(dataset):
16     """
17     Converts Vega dataset into Bokeh ColumnDataSource data
18     """
19     if len(dataset) == 0:
20         return {}
21     data = {k: [] for k, v in dataset[0].items()}
22     for item in dataset:
23         for k, v in item.items():
24             data[k].append(v)
25     data = {k: np.asarray(v) for k, v in data.items()}
26     return data
27 
28 
29 class Vega(PaneBase):
30     """
31     Vega panes allow rendering Vega plots and traces.
32 
33     For efficiency any array objects found inside a Figure are added
34     to a ColumnDataSource which allows using binary transport to sync
35     the figure on bokeh server and via Comms.
36     """
37 
38     margin = param.Parameter(default=(5, 5, 30, 5), doc="""
39         Allows to create additional space around the component. May
40         be specified as a two-tuple of the form (vertical, horizontal)
41         or a four-tuple (top, right, bottom, left).""")
42 
43     priority = 0.8
44 
45     _updates = True
46 
47     @classmethod
48     def is_altair(cls, obj):
49         if 'altair' in sys.modules:
50             import altair as alt
51             return isinstance(obj, alt.api.TopLevelMixin)
52         return False
53 
54     @classmethod
55     def applies(cls, obj):
56         if isinstance(obj, dict) and 'vega' in obj.get('$schema', '').lower():
57             return True
58         return cls.is_altair(obj)
59 
60     @classmethod
61     def _to_json(cls, obj):
62         if isinstance(obj, dict):
63             json = dict(obj)
64             if 'data' in json:
65                 json['data'] = dict(json['data'])
66             return json
67         return obj.to_dict()
68 
69     def _get_sources(self, json, sources):
70         datasets = json.get('datasets', {})
71         for name in list(datasets):
72             if name in sources or isinstance(datasets[name], dict):
73                 continue
74             data = datasets.pop(name)
75             columns = set(data[0]) if data else []
76             if self.is_altair(self.object):
77                 import altair as alt
78                 if (not isinstance(self.object.data, (alt.Data, alt.UrlData)) and
79                     columns == set(self.object.data)):
80                     data = ColumnDataSource.from_df(self.object.data)
81                 else:
82                     data = ds_as_cds(data)
83                 sources[name] = ColumnDataSource(data=data)
84             else:
85                 sources[name] = ColumnDataSource(data=ds_as_cds(data))
86         data = json.get('data', {}).pop('values', {})
87         if data:
88             sources['data'] = ColumnDataSource(data=ds_as_cds(data))
89 
90 
91     @classmethod
92     def _get_dimensions(cls, json, props):
93         if json is None:
94             return
95 
96         view = {}
97         if 'width' in json:
98             view['width'] = json['width']
99         if 'height' in json:
100             view['height'] = json['height']
101         if 'config' in json and 'view' in json['config']:
102             view = json['config']['view']
103         for p in ('width', 'height'):
104             if p not in view:
105                 continue
106             if props.get(p) is None or p in view and props.get(p) < view[p]:
107                 v = view[p]
108                 props[p] = v+22 if isinstance(v, int) else v
109 
110     def _get_model(self, doc, root=None, parent=None, comm=None):
111         if 'panel.models.vega' not in sys.modules:
112             if isinstance(comm, JupyterComm):
113                 self.param.warning('VegaPlot was not imported on instantiation '
114                                    'and may not render in a notebook. Restart '
115                                    'the notebook kernel and ensure you load '
116                                    'it as part of the extension using:'
117                                    '\n\npn.extension(\'vega\')\n')
118             from ..models.vega import VegaPlot
119         else:
120             VegaPlot = getattr(sys.modules['panel.models.vega'], 'VegaPlot')
121 
122         sources = {}
123         if self.object is None:
124             json = None
125         else:
126             json = self._to_json(self.object)
127             self._get_sources(json, sources)
128         props = self._process_param_change(self._init_properties())
129         self._get_dimensions(json, props)
130         model = VegaPlot(data=json, data_sources=sources, **props)
131         if root is None:
132             root = model
133         self._models[root.ref['id']] = (model, parent)
134         return model
135 
136     def _update(self, model):
137         if self.object is None:
138             json = None
139         else:
140             json = self._to_json(self.object)
141             self._get_sources(json, model.data_sources)
142         props = {p : getattr(self, p) for p in list(Layoutable.param)
143                  if getattr(self, p) is not None}
144         self._get_dimensions(json, props)
145         props['data'] = json
146         model.update(**props)
147
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/panel/pane/vega.py b/panel/pane/vega.py
--- a/panel/pane/vega.py
+++ b/panel/pane/vega.py
@@ -62,7 +62,11 @@
         if isinstance(obj, dict):
             json = dict(obj)
             if 'data' in json:
-                json['data'] = dict(json['data'])
+                data = json['data']
+                if isinstance(data, dict):
+                    json['data'] = dict(data)
+                elif isinstance(data, list):
+                    json['data'] = [dict(d) for d in data]
             return json
         return obj.to_dict()
 
@@ -83,9 +87,15 @@
                 sources[name] = ColumnDataSource(data=data)
             else:
                 sources[name] = ColumnDataSource(data=ds_as_cds(data))
-        data = json.get('data', {}).pop('values', {})
-        if data:
-            sources['data'] = ColumnDataSource(data=ds_as_cds(data))
+        data = json.get('data', {})
+        if isinstance(data, dict):
+            data = data.pop('values', {})
+            if data:
+                sources['data'] = ColumnDataSource(data=ds_as_cds(data))
+        elif isinstance(data, list):
+            for d in data:
+                sources[d['name']] = ColumnDataSource(data=ds_as_cds(d['values']))
+            
 
 
     @classmethod

{"golden_diff": "diff --git a/panel/pane/vega.py b/panel/pane/vega.py\n--- a/panel/pane/vega.py\n+++ b/panel/pane/vega.py\n@@ -62,7 +62,11 @@\n         if isinstance(obj, dict):\n             json = dict(obj)\n             if 'data' in json:\n-                json['data'] = dict(json['data'])\n+                data = json['data']\n+                if isinstance(data, dict):\n+                    json['data'] = dict(data)\n+                elif isinstance(data, list):\n+                    json['data'] = [dict(d) for d in data]\n             return json\n         return obj.to_dict()\n \n@@ -83,9 +87,15 @@\n                 sources[name] = ColumnDataSource(data=data)\n             else:\n                 sources[name] = ColumnDataSource(data=ds_as_cds(data))\n-        data = json.get('data', {}).pop('values', {})\n-        if data:\n-            sources['data'] = ColumnDataSource(data=ds_as_cds(data))\n+        data = json.get('data', {})\n+        if isinstance(data, dict):\n+            data = data.pop('values', {})\n+            if data:\n+                sources['data'] = ColumnDataSource(data=ds_as_cds(data))\n+        elif isinstance(data, list):\n+            for d in data:\n+                sources[d['name']] = ColumnDataSource(data=ds_as_cds(d['values']))\n+            \n \n \n     @classmethod\n", "issue": "Vega plot not displaying within a holoviz panel in jupyter notebook\nApparently, vega plots have issues being shown when within a panel in a jupyter notebook. This might have something to do with Panel not serialising the data correctly.\r\n\r\nFor a minimal script showing the issue, see at the bottom of this question.\r\n\r\nMy findings:\r\n\r\n* The vega import works nicely when used outside of a panel: the Vega specification copy/pasted from https://vega.github.io/editor/#/examples/vega/force-directed-layout is visualised as it should be using  `Vega(spec)`.\r\n* When using  `pn.pane.Vega(spec)`  I get an empty space. Running the visualisation externally using  `pn.pane.Vega(spec).show()`  and looking at the source code, I see that the div is empty.\r\n\r\nVersions:\r\n\r\n* panel 0.7.0\r\n* bokeh 1.4.0\r\n* vega 2.6.0\r\n* jupyter 1.0.0\r\n\r\n\r\n```\r\n#!/usr/bin/env python\r\nimport panel as pn\r\nfrom bokeh.plotting import figure, output_notebook, show\r\nfrom vega import VegaLite, Vega\r\npn.extension()\r\npn.extension('vega')\r\noutput_notebook()\r\n\r\nspec = {\r\n  \"$schema\": \"https://vega.github.io/schema/vega/v5.json\",\r\n  \"width\": 400,\r\n  \"height\": 200,\r\n\r\n  \"data\": [\r\n    {\r\n      \"name\": \"table\",\r\n      \"values\": [\r\n        {\"category\": \"A\", \"amount\": 28},\r\n        {\"category\": \"B\", \"amount\": 55},\r\n        {\"category\": \"C\", \"amount\": 43}\r\n      ]\r\n    }\r\n  ],\r\n\r\n  \"scales\": [\r\n    {\r\n      \"name\": \"xscale\",\r\n      \"type\": \"band\",\r\n      \"domain\": {\"data\": \"table\", \"field\": \"category\"},\r\n      \"range\": \"width\"\r\n    },\r\n    {\r\n      \"name\": \"yscale\",\r\n      \"domain\": {\"data\": \"table\", \"field\": \"amount\"},\r\n      \"range\": \"height\"\r\n    }\r\n  ],\r\n\r\n  \"marks\": [\r\n    {\r\n      \"type\": \"rect\",\r\n      \"from\": {\"data\":\"table\"},\r\n      \"encode\": {\r\n        \"enter\": {\r\n          \"x\": {\"scale\": \"xscale\", \"field\": \"category\"},\r\n          \"width\": {\"scale\": \"xscale\", \"band\": 1},\r\n          \"y\": {\"scale\": \"yscale\", \"field\": \"amount\"},\r\n          \"y2\": {\"scale\": \"yscale\", \"value\": 0}\r\n        },\r\n        \"update\": {\r\n          \"fill\": {\"value\": \"steelblue\"}\r\n        }\r\n      }\r\n    }\r\n  ]\r\n}\r\n\r\nVega(spec) # => shows barchart => OK\r\n\r\npn.Column(pn.panel(\"## Vega test\"),\r\n          pn.pane.Vega(spec),\r\n          pn.panel(\"_end of test_\"))\r\n# => shows \"Vega test\", then empty space, the \"end of test\"\r\n\r\npn.Column(pn.panel(\"## Vega test\"),\r\n          pn.panel(spec),\r\n          pn.panel(\"_end of test_\"))\r\n# => shows \"Vega test\", then empty space, the \"end of test\"\r\n```\r\n\r\nThank you,\r\njan.\n", "before_files": [{"content": "from __future__ import absolute_import, division, unicode_literals\n\nimport sys\n\nimport param\nimport numpy as np\n\nfrom bokeh.models import ColumnDataSource\nfrom pyviz_comms import JupyterComm\n\nfrom ..viewable import Layoutable\nfrom .base import PaneBase\n\n\ndef ds_as_cds(dataset):\n    \"\"\"\n    Converts Vega dataset into Bokeh ColumnDataSource data\n    \"\"\"\n    if len(dataset) == 0:\n        return {}\n    data = {k: [] for k, v in dataset[0].items()}\n    for item in dataset:\n        for k, v in item.items():\n            data[k].append(v)\n    data = {k: np.asarray(v) for k, v in data.items()}\n    return data\n\n\nclass Vega(PaneBase):\n    \"\"\"\n    Vega panes allow rendering Vega plots and traces.\n\n    For efficiency any array objects found inside a Figure are added\n    to a ColumnDataSource which allows using binary transport to sync\n    the figure on bokeh server and via Comms.\n    \"\"\"\n\n    margin = param.Parameter(default=(5, 5, 30, 5), doc=\"\"\"\n        Allows to create additional space around the component. May\n        be specified as a two-tuple of the form (vertical, horizontal)\n        or a four-tuple (top, right, bottom, left).\"\"\")\n\n    priority = 0.8\n\n    _updates = True\n\n    @classmethod\n    def is_altair(cls, obj):\n        if 'altair' in sys.modules:\n            import altair as alt\n            return isinstance(obj, alt.api.TopLevelMixin)\n        return False\n\n    @classmethod\n    def applies(cls, obj):\n        if isinstance(obj, dict) and 'vega' in obj.get('$schema', '').lower():\n            return True\n        return cls.is_altair(obj)\n\n    @classmethod\n    def _to_json(cls, obj):\n        if isinstance(obj, dict):\n            json = dict(obj)\n            if 'data' in json:\n                json['data'] = dict(json['data'])\n            return json\n        return obj.to_dict()\n\n    def _get_sources(self, json, sources):\n        datasets = json.get('datasets', {})\n        for name in list(datasets):\n            if name in sources or isinstance(datasets[name], dict):\n                continue\n            data = datasets.pop(name)\n            columns = set(data[0]) if data else []\n            if self.is_altair(self.object):\n                import altair as alt\n                if (not isinstance(self.object.data, (alt.Data, alt.UrlData)) and\n                    columns == set(self.object.data)):\n                    data = ColumnDataSource.from_df(self.object.data)\n                else:\n                    data = ds_as_cds(data)\n                sources[name] = ColumnDataSource(data=data)\n            else:\n                sources[name] = ColumnDataSource(data=ds_as_cds(data))\n        data = json.get('data', {}).pop('values', {})\n        if data:\n            sources['data'] = ColumnDataSource(data=ds_as_cds(data))\n\n\n    @classmethod\n    def _get_dimensions(cls, json, props):\n        if json is None:\n            return\n\n        view = {}\n        if 'width' in json:\n            view['width'] = json['width']\n        if 'height' in json:\n            view['height'] = json['height']\n        if 'config' in json and 'view' in json['config']:\n            view = json['config']['view']\n        for p in ('width', 'height'):\n            if p not in view:\n                continue\n            if props.get(p) is None or p in view and props.get(p) < view[p]:\n                v = view[p]\n                props[p] = v+22 if isinstance(v, int) else v\n\n    def _get_model(self, doc, root=None, parent=None, comm=None):\n        if 'panel.models.vega' not in sys.modules:\n            if isinstance(comm, JupyterComm):\n                self.param.warning('VegaPlot was not imported on instantiation '\n                                   'and may not render in a notebook. Restart '\n                                   'the notebook kernel and ensure you load '\n                                   'it as part of the extension using:'\n                                   '\\n\\npn.extension(\\'vega\\')\\n')\n            from ..models.vega import VegaPlot\n        else:\n            VegaPlot = getattr(sys.modules['panel.models.vega'], 'VegaPlot')\n\n        sources = {}\n        if self.object is None:\n            json = None\n        else:\n            json = self._to_json(self.object)\n            self._get_sources(json, sources)\n        props = self._process_param_change(self._init_properties())\n        self._get_dimensions(json, props)\n        model = VegaPlot(data=json, data_sources=sources, **props)\n        if root is None:\n            root = model\n        self._models[root.ref['id']] = (model, parent)\n        return model\n\n    def _update(self, model):\n        if self.object is None:\n            json = None\n        else:\n            json = self._to_json(self.object)\n            self._get_sources(json, model.data_sources)\n        props = {p : getattr(self, p) for p in list(Layoutable.param)\n                 if getattr(self, p) is not None}\n        self._get_dimensions(json, props)\n        props['data'] = json\n        model.update(**props)\n", "path": "panel/pane/vega.py"}], "after_files": [{"content": "from __future__ import absolute_import, division, unicode_literals\n\nimport sys\n\nimport param\nimport numpy as np\n\nfrom bokeh.models import ColumnDataSource\nfrom pyviz_comms import JupyterComm\n\nfrom ..viewable import Layoutable\nfrom .base import PaneBase\n\n\ndef ds_as_cds(dataset):\n    \"\"\"\n    Converts Vega dataset into Bokeh ColumnDataSource data\n    \"\"\"\n    if len(dataset) == 0:\n        return {}\n    data = {k: [] for k, v in dataset[0].items()}\n    for item in dataset:\n        for k, v in item.items():\n            data[k].append(v)\n    data = {k: np.asarray(v) for k, v in data.items()}\n    return data\n\n\nclass Vega(PaneBase):\n    \"\"\"\n    Vega panes allow rendering Vega plots and traces.\n\n    For efficiency any array objects found inside a Figure are added\n    to a ColumnDataSource which allows using binary transport to sync\n    the figure on bokeh server and via Comms.\n    \"\"\"\n\n    margin = param.Parameter(default=(5, 5, 30, 5), doc=\"\"\"\n        Allows to create additional space around the component. May\n        be specified as a two-tuple of the form (vertical, horizontal)\n        or a four-tuple (top, right, bottom, left).\"\"\")\n\n    priority = 0.8\n\n    _updates = True\n\n    @classmethod\n    def is_altair(cls, obj):\n        if 'altair' in sys.modules:\n            import altair as alt\n            return isinstance(obj, alt.api.TopLevelMixin)\n        return False\n\n    @classmethod\n    def applies(cls, obj):\n        if isinstance(obj, dict) and 'vega' in obj.get('$schema', '').lower():\n            return True\n        return cls.is_altair(obj)\n\n    @classmethod\n    def _to_json(cls, obj):\n        if isinstance(obj, dict):\n            json = dict(obj)\n            if 'data' in json:\n                data = json['data']\n                if isinstance(data, dict):\n                    json['data'] = dict(data)\n                elif isinstance(data, list):\n                    json['data'] = [dict(d) for d in data]\n            return json\n        return obj.to_dict()\n\n    def _get_sources(self, json, sources):\n        datasets = json.get('datasets', {})\n        for name in list(datasets):\n            if name in sources or isinstance(datasets[name], dict):\n                continue\n            data = datasets.pop(name)\n            columns = set(data[0]) if data else []\n            if self.is_altair(self.object):\n                import altair as alt\n                if (not isinstance(self.object.data, (alt.Data, alt.UrlData)) and\n                    columns == set(self.object.data)):\n                    data = ColumnDataSource.from_df(self.object.data)\n                else:\n                    data = ds_as_cds(data)\n                sources[name] = ColumnDataSource(data=data)\n            else:\n                sources[name] = ColumnDataSource(data=ds_as_cds(data))\n        data = json.get('data', {})\n        if isinstance(data, dict):\n            data = data.pop('values', {})\n            if data:\n                sources['data'] = ColumnDataSource(data=ds_as_cds(data))\n        elif isinstance(data, list):\n            for d in data:\n                sources[d['name']] = ColumnDataSource(data=ds_as_cds(d['values']))\n            \n\n\n    @classmethod\n    def _get_dimensions(cls, json, props):\n        if json is None:\n            return\n\n        view = {}\n        if 'width' in json:\n            view['width'] = json['width']\n        if 'height' in json:\n            view['height'] = json['height']\n        if 'config' in json and 'view' in json['config']:\n            view = json['config']['view']\n        for p in ('width', 'height'):\n            if p not in view:\n                continue\n            if props.get(p) is None or p in view and props.get(p) < view[p]:\n                v = view[p]\n                props[p] = v+22 if isinstance(v, int) else v\n\n    def _get_model(self, doc, root=None, parent=None, comm=None):\n        if 'panel.models.vega' not in sys.modules:\n            if isinstance(comm, JupyterComm):\n                self.param.warning('VegaPlot was not imported on instantiation '\n                                   'and may not render in a notebook. Restart '\n                                   'the notebook kernel and ensure you load '\n                                   'it as part of the extension using:'\n                                   '\\n\\npn.extension(\\'vega\\')\\n')\n            from ..models.vega import VegaPlot\n        else:\n            VegaPlot = getattr(sys.modules['panel.models.vega'], 'VegaPlot')\n\n        sources = {}\n        if self.object is None:\n            json = None\n        else:\n            json = self._to_json(self.object)\n            self._get_sources(json, sources)\n        props = self._process_param_change(self._init_properties())\n        self._get_dimensions(json, props)\n        model = VegaPlot(data=json, data_sources=sources, **props)\n        if root is None:\n            root = model\n        self._models[root.ref['id']] = (model, parent)\n        return model\n\n    def _update(self, model):\n        if self.object is None:\n            json = None\n        else:\n            json = self._to_json(self.object)\n            self._get_sources(json, model.data_sources)\n        props = {p : getattr(self, p) for p in list(Layoutable.param)\n                 if getattr(self, p) is not None}\n        self._get_dimensions(json, props)\n        props['data'] = json\n        model.update(**props)\n", "path": "panel/pane/vega.py"}]}