Mpld3: "TypeError: *** is not JSON serializable" bei Verwendung von xticks

Erstellt am 11. Mai 2014  ·  29Kommentare  ·  Quelle: mpld3/mpld3

Ich bin auf diesen Fehler gestoßen, als ich an Pandas Plot herumgefummelt habe, als ich das Argument xticks .

Der Konzeptnachweis ist hier:
http://nbviewer.ipython.org/gist/edvakf/a47a41ace10afbd891ff
(Änderung von http://pandas.pydata.org/pandas-docs/stable/visualization.html )

Hilfreichster Kommentar

Ich habe dies behoben, indem ich die Zeile hinzugefügt habe

elif isinstance(obj, (numpy.ndarray,)):
        return obj.tolist()

zu /mpld3/_display.py: NumpyEncoder

Alle 29 Kommentare

Ah - es sieht so aus, als ob mplexporter fälschlicherweise annimmt, dass xticks eine Liste sind. Das ist ein Fehler.

In der Zwischenzeit sollte es funktionieren, wenn Sie Ihre xticks manuell in eine Liste umwandeln.

Tatsächlich ist das nicht der Fall. Das heißt, Folgendes funktioniert einwandfrei:

fig = plt.figure()
ax = fig.add_subplot(111, xticks=np.arange(11))
ax.plot([0, 10], [0, 10], '-k')
mpld3.show()

Pandas macht hier mit seinen Ticks etwas Seltsames: Der Fehler sagt, dass 2000 nicht serialisierbar ist, was verrückt ist. Hat Pandas eine Art eingebauten nicht-serialisierbaren Gleitkommatyp?

Es ist nicht die Zahl 2000, sondern das Jahr. Willkommen in der datetime Hölle.
(Bearbeitung 19.06.2014: es scheint, dass ich mich geirrt habe, dass datetime das Problem ist ...)

Ugh... Ich bin mir nicht sicher, wie ich das am besten handhaben soll. Irgendwelche Gedanken?

Hilft es, das to_json in pandas ?

http://pandas.pydata.org/pandas-docs/dev/io.html#date -handling

Hilft es, to_json in Pandas zu verwenden?

Vielleicht, aber dann müssen wir für viele Dinge innerhalb des Codes eine try ... except Anweisung ausführen (dh tun Sie es in eine Richtung, wenn der Wert eine Pandas-Variable ist, tun Sie es anders) und stellen Sie dann sicher, dass die Achsenbeschriftungen auf der Javascript-Seite jede JSON-Struktur verarbeiten können, die Pandas ausgibt. Ich würde es vorziehen, diese Komplexität nicht hinzuzufügen, da es sich nach einer sehr fragilen Lösung und einem Wartungsalbtraum anhört.

Ich verstehe. Dies läuft darauf hinaus, dass Python nicht in der Lage ist, die Json-Serialisierungsmethode für die benutzerdefinierte Klasse dann bereitzustellen. Sie können dieses Problem schließen.

Wir sollten es offen lassen... vielleicht gibt es einen besseren Weg, damit umzugehen. Ich denke drüber nach.

Warte eine Sekunde, das scheint für mich in Python 2.7 gut zu funktionieren. Könnte es nur ein Python3-Problem sein?

In [56]: matplotlib.__version__
Out[56]: '1.3.1'

In [57]: pandas.__version__
Out[57]: '0.13.1'

Hallo alle,
Ich bin mir nicht sicher, ob es damit zusammenhängt, aber ich bekomme ein ähnliches Problem, wenn ich versuche, dieses Seaborn-Diagramm zu zeichnen: http://www.stanford.edu/~mwaskom/software/seaborn/examples/many_facets.html

mpld3.fig_to_html(grid.fig, 'test.html')
/home/vagrant/graph/local/lib/python2.7/site-packages/mpld3/mplexporter/exporter.py:82: UserWarni ng: Blended transforms not yet supported. Zoom behavior may not work as expected.
  warnings.warn("Blended transforms not yet supported. "
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/vagrant/graph/local/lib/python2.7/site-packages/mpld3/_display.py", line 236, in fig_to_html
    figure_json=json.dumps(figure_json),
  File "/usr/lib/python2.7/json/__init__.py", line 231, in dumps
    return _default_encoder.encode(obj)
  File "/usr/lib/python2.7/json/encoder.py", line 201, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "/usr/lib/python2.7/json/encoder.py", line 264, in iterencode
    return _iterencode(o, 0)
  File "/usr/lib/python2.7/json/encoder.py", line 178, in default
    raise TypeError(repr(o) + " is not JSON serializable")
TypeError: 0 is not JSON serializable

Das Problem besteht darin, dass numpy.int64-Nummern intern verwendet werden und diese standardmäßig nicht mit Json serialisierbar sind.
Es sollte einen Hook in der Bibliothek geben, um einen json.JSONEncoder bereitzustellen, um dies zu handhaben.

Nur um Raum für Ideen zu geben:

Ich habe das gleiche Problem, bin aber mit Django verbunden, das ich als Backend für das Projekt verwende, das ich in dem Projekt verwende, in dem ich mpld3 verwende.

Ich habe versucht, ein numpy-Array zu serialisieren, und habe diesen Fehler bei der Verwendung von django 1.6 erhalten. Ich habe ein Downgrade auf 1.5 gemacht und es funktioniert. Ich habe den Grund dafür gefunden, dass ab 1.6 die Serialisierung mit json erfolgt, ab 1.5 über Pickle.

Ich hoffe, das kann Ihnen helfen, das Problem zu finden.

Med vennlig hilsen,
Gerardo de La Riva Espinosa
Høgskolelektor
Høgskolen i Gjøvik
E-Mail: Gerardo. [email protected]
Mobil: +47 950 13 322

Am 19. Juni 2014 um 16:56 Uhr schrieb lvasseur [email protected] :

Hallo alle,
Ich bin mir nicht sicher, ob es damit zusammenhängt, aber ich bekomme ein ähnliches Problem, wenn ich versuche, dieses Seaborn-Diagramm zu zeichnen: http://www.stanford.edu/~mwaskom/software/seaborn/examples/many_facets.html

mpld3.fig_to_html(grid.fig, 'test.html')
/home/vagrant/graph/local/lib/python2.7/site-packages/mpld3/mplexporter/exporter.py:82: UserWarning: Blended Transformations noch nicht unterstützt. Das Zoomverhalten funktioniert möglicherweise nicht wie erwartet.
warnings.warn("Blended Transformationen werden noch nicht unterstützt. "
Traceback (letzter Anruf zuletzt):
Datei "", Zeile 1, in
Datei "/home/vagrant/graph/local/lib/python2.7/site-packages/mpld3/_display.py", Zeile 236, in fig_to_html
figure_json=json.dumps(figure_json),
Datei "/usr/lib/python2.7/json/__init__.py", Zeile 231 in Dumps
return _default_encoder.encode(obj)
Datei "/usr/lib/python2.7/json/encoder.py", Zeile 201, in encode
chunks = self.iterencode(o, _one_shot=True)
Datei "/usr/lib/python2.7/json/encoder.py", Zeile 264, in iterencode
_iterencode(o, 0) zurückgeben
Datei "/usr/lib/python2.7/json/encoder.py", Zeile 178, standardmäßig
raise TypeError(repr(o) + "ist nicht JSON serialisierbar")
TypeError: 0 ist nicht durch JSON serialisierbar
Das Problem besteht darin, dass numpy.int64-Nummern intern verwendet werden und diese standardmäßig nicht mit Json serialisierbar sind.
Es sollte einen Hook in der Bibliothek geben, um einen json.JSONEncoder bereitzustellen, um dies zu handhaben.


Antworten Sie direkt auf diese E-Mail oder zeigen Sie sie auf GitHub an.

Zu Ihrer Information,

    from json import JSONEncoder
    class MyEncoder(JSONEncoder):
        def default(self, obj):
            if isinstance(obj, numpy.int64):
                return int(obj)
            return JSONEncoder.default(self, obj)

    return template.render(figid=json.dumps(figid),
                           d3_url=d3_url,
                           mpld3_url=mpld3_url,
                           figure_json=json.dumps(figure_json, cls=MyEncoder),
                           extra_css=extra_css,
                           extra_js=extra_js)

behebt das Problem in /mpld3/_display.py : fig_to_html

Ich habe jetzt keine Zeit, es zu versuchen, aber es sieht so aus, als wäre dies ein Problem und die richtige Richtung für eine Lösung. Die json.dump Dokumente lassen mich denken, dass es mit der Option default eine etwas leichtere Lösung gibt, obwohl sie am Ende vielleicht nur eine Zeile kürzer ist. Bist du bereit für einen Pull-Request?

Ich habe erwartet, dass dies durch PR #213 behoben wird, aber das Ipython-Notebook aus dem ursprünglichen Beitrag funktioniert immer noch nicht für mich. Kann es noch jemand versuchen?

Das probiere ich irgendwann mal aus

Immer noch verwirrt darüber ... Ich bin mir nicht sicher, ob #213 hier tatsächlich etwas behoben hat. Ich kann int64-Objekte ohne sie serialisieren ...

wurde das gelöst?
Ich kann anscheinend keine von Pandas generierte Figur fig_to_html erstellen ( ich bekomme TypeError: 0 is not JSON serializable ). Abbildung wird gut generiert.
Wenn ich es mit plt.bar erneut versuchte, erhalte ich auch den Fehler, wenn ich yticks mit benutzerdefinierten Zeichenfolgen verwende.

Wie löst man?

Nicht sicher. Es scheint ein Problem zu geben, dass Achsenbeschriftungen nicht serialisierbare Versionen von Ganzzahlen sind. Wenn Sie etwas herausgefunden haben, lassen Sie es uns wissen.

Wollte nur darauf hinweisen, dass ich diesen Fehler bei der Verwendung bekomme

dates = df.Date.apply(lambda dt: dt.strftime('%B')[:3] + dt.strftime(' %d')).values
plt.xticks(x, dates, rotation='vertical')

aber nicht mit

ax.set_xticklabels(dates, rotation='vertical')

Hoffe das hilft.

Bearbeiten: Bei weiterer Überprüfung erzeugt die letztere Version zwar keinen Fehler, die Xticks der resultierenden Figur werden jedoch nicht wirklich gesetzt.

Edit 2: Meine schlechten, habe gerade herausgefunden, dass Häkchen nicht unterstützt werden (#22).

FWIW, die Verwendung von Boxplots kann das Problem reproduzieren:

import numpy as np, mpld3
np.random.seed(937)
data = np.random.lognormal(size=(37, 4), mean=1.5, sigma=1.75)
labels = list('ABCD')
fs = 10  # fontsize

fig, axes = plt.subplots(1, 1, figsize=(6, 6)) 
axes.boxplot(data, labels=labels)
axes.set_title('Default', fontsize=fs)

html_fig = mppld3.fig_to_html(fig)

Konkret sind hier die Versionen von Pip Freeze

cycler==0.10.0
Jinja2==2.8
MarkupSafe==0.23
matplotlib==1.5.1
mpld3==0.2
numpy==1.10.4
pandas==0.17.1
ptyprocess==0.5.1
pyparsing==2.1.0
python-dateutil==2.5.0
pytz==2015.7
six==1.10.0
wheel==0.29.0

für Python 3.4.3.

Der von @lvasseur vorgeschlagene

Damit das ursprüngliche Beispiel funktioniert, verwenden Sie [float(x) for x in range(2000,2002)] anstelle von np.arange(2000,2002,1).

Ich bin mir nicht sicher, ob es damit zusammenhängt, aber ich bekomme ein ähnliches Problem, wenn ich versuche, dieses Seaborn-Diagramm zu zeichnen: http://www.stanford.edu/~mwaskom/software/seaborn/examples/many_facets.html

Ich erhalte denselben Fehler, wenn ich mtld3.display(fig) für die Seaborn Barplot-Figur versuche:

TypeError: 0 ist nicht durch JSON serialisierbar

Kann jemand mit mpld3 seefeste Plots rendern?

Dies scheint zu passieren, weil es nan in Datenwerten gibt. Wenn ich bei _display.py unterbreche:243nan durch None in figure_json dict, ich erhalte die erwartete Ausgabe.

Bearbeiten: oben scheint das Problem nicht zu lösen (ich habe im Debug-Interpreter getestet, wo es funktionierte, aber nicht bei Verwendung von mpld3).
Das Rendern von sns.barplot() funktioniert also nicht, während das Rendern von plt.bar() funktioniert. Ich konnte keinen offensichtlichen Unterschied in den Zahlen beider Plots feststellen, aber der bereitgestellte Patch (https://github.com/mpld3/mpld3/pull/213) löste das Problem.

Ich habe dies behoben, indem ich die Zeile hinzugefügt habe

elif isinstance(obj, (numpy.ndarray,)):
        return obj.tolist()

zu /mpld3/_display.py: NumpyEncoder

Danke @jaklinger das hat

@jaklinger , Hallo zusammen, danke für deinen Vorschlag, er funktioniert einwandfrei! Ich wollte nur eine Sache klarstellen - ich habe das numpy-Array in ein Wörterbuch umgewandelt und versucht, es zurückzugeben, aber es wurde der Fehler "float 32 is not json serializable" ausgegeben, obwohl es kein Problem mit dem Wörterbuch gab, es gedruckt und überprüft wurde. Durch die Verwendung Ihrer tolist()-Methode wurde das Array in eine Python-Liste konvertiert.
zurück :[100. 0. 0. 0. 0.]
mit tolist: [100.0, 0.0, 0.0, 0.0, 0.0] und es wurde perfekt zurückgegeben.
Was war denn genau das Problem? Vielen Dank im Voraus.

@padmaksha18 Ich bin mir nicht 100% sicher, was du mit meinst

konvertierte das numpy-Array in ein Wörterbuch

aber (kurz) numpy und python Typen sind nicht gleich ( float32 ist nicht gleich float ; ein array ist nicht dasselbe wie list usw.) und die JSONEncoder-Klasse "erlaubt" nur native python Typen. Der Sinn dieser Funktion (die den neuen Fix enthält) besteht also darin, die Eingabe obj in native python Äquivalente umzuwandeln.

@jaklinger :Hallo Joel, vielen Dank nochmal. Mit der Konvertierung in ein Wörterbuch meinte ich nur, dass ich zwei solcher Arrays genommen und ein Schlüssel-Wert-Paar gebildet habe, sorry, dass ich es nicht klar erklärt habe. Vielen Dank, dass Sie mir diese Sache klar gemacht haben, ich muss sie zuerst in den nativen Python-Typ konvertieren und das war das Problem. Ich wollte nur noch eine Sache klarstellen, zum Beispiel, wenn Sie ein Wörterbuch nicht jsonifizieren und versuchen, es so zurückzugeben, wie es ist, kommt dann die jsonencoder-Klasse ins Bild? Vielen Dank!

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen

Verwandte Themen

jakevdp picture jakevdp  ·  4Kommentare

ledmonster picture ledmonster  ·  4Kommentare

ajasja picture ajasja  ·  17Kommentare

andreatramacere picture andreatramacere  ·  8Kommentare

pranet picture pranet  ·  6Kommentare