Ошибка сериализации Json с использованием matplotlib mpld3 с LinkedBrush

Пример mpld3 (matplotlib на d3) для LinkedBrush http://mpld3.github.io/examples/linked_brush.html содержит следующий пример кода:

import numpy as np
import matplotlib
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris

import mpld3
from mpld3 import plugins, utils


data = load_iris()
X = data.data
y = data.target

# dither the data for clearer plotting
X += 0.1 * np.random.random(X.shape)

fig, ax = plt.subplots(4, 4, sharex="col", sharey="row", figsize=(8, 8))
fig.subplots_adjust(left=0.05, right=0.95, bottom=0.05, top=0.95,
                    hspace=0.1, wspace=0.1)

for i in range(4):
    for j in range(4):
        points = ax[3 - i, j].scatter(X[:, j], X[:, i],
                                      c=y, s=40, alpha=0.6)

# remove tick labels
for axi in ax.flat:
    for axis in [axi.xaxis, axi.yaxis]:
        axis.set_major_formatter(plt.NullFormatter())

# Here we connect the linked brush plugin
plugins.connect(fig, plugins.LinkedBrush(points))

mpld3.show()

Хотя общедоступная веб-страница показывает матрицу связанных выходов, при ее локальном запуске возникает ошибка сериализации json:

Traceback (most recent call last):
  File "/git/scalatesting/src/main/python/mpld3_linkedbrush.py", line 34, in <module>
    mpld3.show()
  File "/usr/local/lib/python2.7/site-packages/mpld3/_display.py", line 358, in show
    html = fig_to_html(fig, **kwargs)
  File "/usr/local/lib/python2.7/site-packages/mpld3/_display.py", line 251, in fig_to_html
    figure_json=json.dumps(figure_json, cls=NumpyEncoder),
  File "/usr/local/Cellar/python/2.7.14/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/__init__.py", line 251, in dumps
    sort_keys=sort_keys, **kw).encode(obj)
  File "/usr/local/Cellar/python/2.7.14/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/encoder.py", line 207, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "/usr/local/Cellar/python/2.7.14/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/encoder.py", line 270, in iterencode
    return _iterencode(o, 0)
  File "/usr/local/lib/python2.7/site-packages/mpld3/_display.py", line 138, in default
    return json.JSONEncoder.default(self, obj)
  File "/usr/local/Cellar/python/2.7.14/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/encoder.py", line 184, in default
    raise TypeError(repr(o) + " is not JSON serializable")
TypeError: array([ 1.]) is not JSON serializable

Местная среда

$pip show mpld3
Name: mpld3
Version: 0.3
Summary: D3 Viewer for Matplotlib
Home-page: http://mpld3.github.com
Author: Jake VanderPlas
Author-email: [email protected]
License: BSD 3-clause
Location: /usr/local/lib/python2.7/site-packages

и

$python -V
Python 2.7.14

mpld3 был установлен сегодня. Есть ли проблема с версиями mpld3? Любые другие предложения?


person WestCoastProjects    schedule 19.11.2017    source источник
comment
Похоже, это пример этой ошибки, такое же решение предлагается в stackoverflow.com/questions/26646362/ - вызов points.tolist() перед подключением плагина   -  person snakecharmerb    schedule 19.11.2017
comment
@snakecharmerb Не стесняйтесь сделать это ответом   -  person WestCoastProjects    schedule 19.11.2017


Ответы (2)


Основываясь на комментарии @snakecharmerb, я разветвился с mpld3, ввел предложенное исправление и установил pip из моей новой ветки на github.

Исправление находится здесь: https://github.com/javadba/mpld3/tree/display_fix . Его можно установить через:

python -m pip install --user "git+https://github.com/javadba/mpld3@display_fix"

Это работает хорошо: ошибка json serialization исчезла, и связь между 9 диаграммами работает правильно:

введите описание изображения здесь

person WestCoastProjects    schedule 19.11.2017
comment
Не могу поверить, что они до сих пор не оценили твой пиар. Это заставило меня ЧАСОВ узнать. Спасибо за это кстати!! - person Payam; 12.06.2020

Для меня решение, данное здесь, не сработало.

У меня был сетевой график для визуализации:

import matplotlib.pyplot as plt
import numpy as np
import mpld3

import networkx as nx
G = nx.path_graph(4)
pos = nx.spring_layout(G)

fig, ax = plt.subplots(subplot_kw=dict(facecolor='#EEEEEE'))
scatter = nx.draw_networkx_nodes(G, pos, ax=ax)
nx.draw_networkx_edges(G, pos, ax=ax)

labels = G.nodes()
tooltip = mpld3.plugins.PointLabelTooltip(scatter, labels=labels)
mpld3.plugins.connect(fig, tooltip)

mpld3.show()

Затем он выдал ошибку «JSON не сериализуемый». Я нашел приведенную выше ссылку и попытался исправить. Исправление по сути говорит, что если объект имеет тип numpy.ndarray, то изменить его на список.

Но тип объекта G.nodes — это networkx.classes.reportviews.NodeView, а не numpy.ndarray; таким образом, это не работало.

Итак, я изменил файл _display.py, добавив import networkx, и добавил следующие 2 строки в функцию default в классе NumpyEncoder, чтобы она заработала:

elif isinstance(obj,networkx.classes.reportviews.NodeView):
    return list(obj)

Теперь это работает:

введите здесь описание изображения

person Kristada673    schedule 20.05.2019
comment
Таким образом, оказывается, что решение для различных типов данных требует настройки для конкретных классов. Спасибо за обновление - person WestCoastProjects; 20.05.2019