dimod
dimod copied to clipboard
_to_networkx_graph() creates unserializable vartype obj
Description
Try to convert a BQM (either default or AdjDictBQM) to a networkx graph, then use bokeh to plot, and bokeh gives a TypeError: Object of type 'Vartype' is not JSON serializable
error.
Steps To Reproduce
import dimod
import networkx as nx
from bokeh.io import show
from bokeh.plotting import figure, from_networkx
bqm = dimod.BQM.from_ising({}, {('ab'): 1})
# bqm = dimod.AdjDictBQM.from_ising({}, {('ab'): 1})
G = dimod.to_networkx_graph(bqm)
plot = figure(title="Networkx Integration Demonstration", x_range=(-1.1,1.1), y_range=(-1.1,1.1),
tools="", toolbar_location=None)
graph = from_networkx(G, nx.spring_layout, scale=2, center=(0,0))
plot.renderers.append(graph)
show(plot)
Expected Behavior Graph output should be serializable
Environment
- OS: Ubuntu 16
- Python version: 3.6 or 3.7
Additional Context Workaround: convert without the vartype.
G = nx.Graph()
G.add_nodes_from(bqm.variables)
G.add_edges_from(bqm.quadratic)
Below is the full error message:
TypeError Traceback (most recent call last)
<ipython-input-18-c8982eef3cb2> in <module>()
18 plot.renderers.append(graph)
19
---> 20 show(plot)
/opt/conda/lib/python3.6/site-packages/bokeh/io/showing.py in show(obj, browser, new, notebook_handle, notebook_url, **kw)
137 return run_notebook_hook(state.notebook_type, 'app', obj, state, notebook_url, **kw)
138
--> 139 return _show_with_state(obj, state, browser, new, notebook_handle=notebook_handle)
140
141 #-----------------------------------------------------------------------------
/opt/conda/lib/python3.6/site-packages/bokeh/io/showing.py in _show_with_state(obj, state, browser, new, notebook_handle)
171
172 if state.notebook:
--> 173 comms_handle = run_notebook_hook(state.notebook_type, 'doc', obj, state, notebook_handle)
174 shown = True
175
/opt/conda/lib/python3.6/site-packages/bokeh/io/notebook.py in run_notebook_hook(notebook_type, action, *args, **kw)
296 if _HOOKS[notebook_type][action] is None:
297 raise RuntimeError("notebook hook for %r did not install %r action" % notebook_type, action)
--> 298 return _HOOKS[notebook_type][action](*args, **kw)
299
300 #-----------------------------------------------------------------------------
/opt/conda/lib/python3.6/site-packages/bokeh/io/notebook.py in show_doc(obj, state, notebook_handle)
506 from ..embed.notebook import notebook_content
507 comms_target = make_id() if notebook_handle else None
--> 508 (script, div, cell_doc) = notebook_content(obj, comms_target)
509
510 publish_display_data({HTML_MIME_TYPE: div})
/opt/conda/lib/python3.6/site-packages/bokeh/embed/notebook.py in notebook_content(model, notebook_comms_target, theme)
83 # has models with the same IDs as they were started with
84 with OutputDocumentFor([model], apply_theme=theme, always_new=True) as new_doc:
---> 85 (docs_json, [render_item]) = standalone_docs_json_and_render_items([model])
86
87 div = div_for_render_item(render_item)
/opt/conda/lib/python3.6/site-packages/bokeh/embed/util.py in standalone_docs_json_and_render_items(models, suppress_callback_warning)
292 docs_json = {}
293 for doc, (docid, _) in docs.items():
--> 294 docs_json[docid] = doc.to_json()
295
296 render_items = []
/opt/conda/lib/python3.6/site-packages/bokeh/document/document.py in to_json(self)
899 # this is a total hack to go via a string, needed because
900 # our BokehJSONEncoder goes straight to a string.
--> 901 doc_json = self.to_json_string()
902 return loads(doc_json)
903
/opt/conda/lib/python3.6/site-packages/bokeh/document/document.py in to_json_string(self, indent)
928 }
929
--> 930 return serialize_json(json, indent=indent)
931
932 def validate(self):
/opt/conda/lib/python3.6/site-packages/bokeh/core/json_encoder.py in serialize_json(obj, pretty, indent, **kwargs)
164 indent = 2
165
--> 166 return json.dumps(obj, cls=BokehJSONEncoder, allow_nan=False, indent=indent, separators=separators, sort_keys=True, **kwargs)
167
168
/opt/conda/lib/python3.6/json/__init__.py in dumps(obj, skipkeys, ensure_ascii, check_circular, allow_nan, cls, indent, separators, default, sort_keys, **kw)
236 check_circular=check_circular, allow_nan=allow_nan, indent=indent,
237 separators=separators, default=default, sort_keys=sort_keys,
--> 238 **kw).encode(obj)
239
240
/opt/conda/lib/python3.6/json/encoder.py in encode(self, o)
197 # exceptions aren't as detailed. The list call should be roughly
198 # equivalent to the PySequence_Fast that ''.join() would do.
--> 199 chunks = self.iterencode(o, _one_shot=True)
200 if not isinstance(chunks, (list, tuple)):
201 chunks = list(chunks)
/opt/conda/lib/python3.6/json/encoder.py in iterencode(self, o, _one_shot)
255 self.key_separator, self.item_separator, self.sort_keys,
256 self.skipkeys, _one_shot)
--> 257 return _iterencode(o, 0)
258
259 def _make_iterencode(markers, _default, _encoder, _indent, _floatstr,
/opt/conda/lib/python3.6/site-packages/bokeh/core/json_encoder.py in default(self, obj)
259
260 else:
--> 261 return self.transform_python_types(obj)
262
263 #-----------------------------------------------------------------------------
/opt/conda/lib/python3.6/site-packages/bokeh/core/json_encoder.py in transform_python_types(self, obj)
226
227 else:
--> 228 return super().default(obj)
229
230 def default(self, obj):
/opt/conda/lib/python3.6/json/encoder.py in default(self, o)
178 """
179 raise TypeError("Object of type '%s' is not JSON serializable" %
--> 180 o.__class__.__name__)
181
182 def encode(self, o):
TypeError: Object of type 'Vartype' is not JSON serializable
Worth noting that networkx.Graph
is not itself JSON-serializable, Bokeh has implemented a custom encoder BokehJSONEncoder
.
So I think the request is really "Graph output should be serializable by Bokeh's custom encoder"
IMO this is not an easy fix. Simplest would be del G.vartype
.
Error persists (TypeError: Object of type 'Vartype' is not JSON serializable
) even after deleting it.
G = dimod.to_networkx_graph(bqm)
print(G.vartype)
del G.vartype
print(G.vartype)
Vartype.SPIN
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-29-4497731d6b2b> in <module>()
2 print(G.vartype)
3 del G.vartype
----> 4 print(G.vartype)
AttributeError: 'Graph' object has no attribute 'vartype'
try plotting again:
show(plot)
TypeError Traceback (most recent call last)
...
TypeError: Object of type 'Vartype' is not JSON serializable
Ah, got it, comes from https://github.com/dwavesystems/dimod/blob/126a9056c4226d6955395620efb94ebee07581a5/dimod/converters.py#L49
Ok. I think your workaround it best for now.