We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
'str' object has no attribute 'items' when visualising Vega plot of network using Panel
When running `pn.pane.Vega(spec)` on a network spec (from the vega example showing a force-directed network of the Miserables characters), I get an error in line 21 of the `pane.py` source file. The error:

```
~/anaconda3/envs/i0u19a_jupyter/lib/python3.7/site-packages/panel/pane/vega.py in ds_as_cds(dataset)
     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():

AttributeError: 'str' object has no attribute 'items'
```

See the image for a screenshot of the complete error message. The command used was `pn.pane.Vega(spec)`, the error what is shown above, and the output was `Vega(dict)`.

![Image 2: Bug after `pn.pane.Vega(spec)`](https://discourse.holoviz.org/uploads/default/optimized/1X/535d10eca1d1b97d6839c9d0b08d8c9af87e5ade_2_1274x1000.png)

--- 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                 data = json['data']
66                 if isinstance(data, dict):
67                     json['data'] = dict(data)
68                 elif isinstance(data, list):
69                     json['data'] = [dict(d) for d in data]
70             return json
71         return obj.to_dict()
72 
73     def _get_sources(self, json, sources):
74         datasets = json.get('datasets', {})
75         for name in list(datasets):
76             if name in sources or isinstance(datasets[name], dict):
77                 continue
78             data = datasets.pop(name)
79             columns = set(data[0]) if data else []
80             if self.is_altair(self.object):
81                 import altair as alt
82                 if (not isinstance(self.object.data, (alt.Data, alt.UrlData)) and
83                     columns == set(self.object.data)):
84                     data = ColumnDataSource.from_df(self.object.data)
85                 else:
86                     data = ds_as_cds(data)
87                 sources[name] = ColumnDataSource(data=data)
88             else:
89                 sources[name] = ColumnDataSource(data=ds_as_cds(data))
90         data = json.get('data', {})
91         if isinstance(data, dict):
92             data = data.pop('values', {})
93             if data:
94                 sources['data'] = ColumnDataSource(data=ds_as_cds(data))
95         elif isinstance(data, list):
96             for d in data:
97                 sources[d['name']] = ColumnDataSource(data=ds_as_cds(d['values']))
98             
99 
100 
101     @classmethod
102     def _get_dimensions(cls, json, props):
103         if json is None:
104             return
105 
106         view = {}
107         if 'width' in json:
108             view['width'] = json['width']
109         if 'height' in json:
110             view['height'] = json['height']
111         if 'config' in json and 'view' in json['config']:
112             view = json['config']['view']
113         for p in ('width', 'height'):
114             if p not in view:
115                 continue
116             if props.get(p) is None or p in view and props.get(p) < view[p]:
117                 v = view[p]
118                 props[p] = v+22 if isinstance(v, int) else v
119 
120     def _get_model(self, doc, root=None, parent=None, comm=None):
121         if 'panel.models.vega' not in sys.modules:
122             if isinstance(comm, JupyterComm):
123                 self.param.warning('VegaPlot was not imported on instantiation '
124                                    'and may not render in a notebook. Restart '
125                                    'the notebook kernel and ensure you load '
126                                    'it as part of the extension using:'
127                                    '\n\npn.extension(\'vega\')\n')
128             from ..models.vega import VegaPlot
129         else:
130             VegaPlot = getattr(sys.modules['panel.models.vega'], 'VegaPlot')
131 
132         sources = {}
133         if self.object is None:
134             json = None
135         else:
136             json = self._to_json(self.object)
137             self._get_sources(json, sources)
138         props = self._process_param_change(self._init_properties())
139         self._get_dimensions(json, props)
140         model = VegaPlot(data=json, data_sources=sources, **props)
141         if root is None:
142             root = model
143         self._models[root.ref['id']] = (model, parent)
144         return model
145 
146     def _update(self, model):
147         if self.object is None:
148             json = None
149         else:
150             json = self._to_json(self.object)
151             self._get_sources(json, model.data_sources)
152         props = {p : getattr(self, p) for p in list(Layoutable.param)
153                  if getattr(self, p) is not None}
154         self._get_dimensions(json, props)
155         props['data'] = json
156         model.update(**props)
157
```
--- 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
@@ -94,10 +94,10 @@
                 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']))
+                if 'values' in d:
+                    sources[d['name']] = ColumnDataSource(data=ds_as_cds(d.pop('values')))
             
 
-
     @classmethod
     def _get_dimensions(cls, json, props):
         if json is None:

{"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@@ -94,10 +94,10 @@\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+                if 'values' in d:\n+                    sources[d['name']] = ColumnDataSource(data=ds_as_cds(d.pop('values')))\n             \n \n-\n     @classmethod\n     def _get_dimensions(cls, json, props):\n         if json is None:\n", "issue": "'str' object has no attribute 'items' when visualising Vega plot of network using Panel\nWhen running `pn.pane.Vega(spec)` on a network spec (from the vega example showing a force-directed network of the Miserables characters), I get an error in line 21 of the `pane.py` source file. The error:\r\n\r\n```\r\n~/anaconda3/envs/i0u19a_jupyter/lib/python3.7/site-packages/panel/pane/vega.py in ds_as_cds(dataset)\r\n     19     if len(dataset) == 0:\r\n     20         return {}\r\n---> 21     data = {k: [] for k, v in dataset[0].items()}\r\n     22     for item in dataset:\r\n     23         for k, v in item.items():\r\n\r\nAttributeError: 'str' object has no attribute 'items'\r\n```\r\n\r\nSee the image for a screenshot of the complete error message. The command used was `pn.pane.Vega(spec)`, the error what is shown above, and the output was `Vega(dict)`.\r\n\r\n![Image 2: Bug after `pn.pane.Vega(spec)`](https://discourse.holoviz.org/uploads/default/optimized/1X/535d10eca1d1b97d6839c9d0b08d8c9af87e5ade_2_1274x1000.png)\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                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"}], "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                if 'values' in d:\n                    sources[d['name']] = ColumnDataSource(data=ds_as_cds(d.pop('values')))\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"}]}