Mpld3: "TypeError: *** bukan JSON serializable" saat menggunakan xticks

Dibuat pada 11 Mei 2014  ·  29Komentar  ·  Sumber: mpld3/mpld3

Saya menemukan kesalahan ini ketika saya mengutak-atik plot panda, ketika saya menggunakan argumen xticks .

Bukti konsep ada di sini:
http://nbviewer.ipython.org/gist/edvakf/a47a41ace10afbd891ff
(modifikasi http://pandas.pydata.org/pandas-docs/stable/visualization.html )

Komentar yang paling membantu

Saya memperbaikinya dengan menambahkan baris

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

ke /mpld3/_display.py: NumpyEncoder

Semua 29 komentar

Ah - sepertinya mplexporter salah mengasumsikan bahwa xticks adalah daftar. Itu bug.

Sementara itu, jika Anda secara manual mengonversi xticks Anda ke daftar, itu akan berfungsi.

Sebenarnya, bukan itu masalahnya. Artinya, berikut ini berfungsi dengan baik:

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

Pandas melakukan sesuatu yang aneh di sini dengan kutunya: kesalahan mengatakan bahwa 2000 tidak dapat diserialisasi, yang gila. Apakah Pandas memiliki semacam tipe floating point yang tidak dapat serial?

Ini bukan angka 2000, ini tahun. Selamat datang di neraka datetime .
(edit 19/6/2014: sepertinya saya salah tentang datetime menjadi masalah ...)

Ugh... Aku tidak yakin bagaimana cara terbaik untuk menanganinya. Ada pikiran?

Apakah membantu menggunakan to_json di pandas ?

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

Apakah membantu menggunakan to_json di panda?

Mungkin, tapi kemudian kita harus melakukan pernyataan try ... except untuk banyak hal di dalam kode (yaitu lakukan satu cara jika nilainya adalah variabel Pandas, lakukan dengan cara lain) dan kemudian pastikan label sumbu di sisi javascript dapat menangani struktur JSON apa pun yang Pandas putuskan untuk dikeluarkan. Saya lebih suka untuk tidak menambahkan tingkat kerumitan itu, karena kedengarannya seperti solusi yang sangat rapuh dan mimpi buruk pemeliharaan.

Jadi begitu. Ini bermuara pada ketidakmampuan Python untuk mengekspos metode serialisasi json untuk kelas yang ditentukan pengguna. Anda dapat menutup masalah ini.

Kita harus membiarkannya terbuka... mungkin ada cara yang lebih baik untuk menangani ini. Saya akan berpikir tentang hal ini.

Tunggu sebentar, ini sepertinya berfungsi dengan baik untuk saya di Python 2.7. Mungkinkah ini hanya masalah Python3?

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

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

Halo semua,
Tidak yakin apakah terkait, tetapi saya mendapatkan masalah serupa ketika mencoba memplot grafik seaborn ini: 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

Masalahnya adalah nomor numpy.int64 digunakan secara internal, dan ini tidak json serializable secara default.
Harus ada pengait di perpustakaan untuk menyediakan json.JSONEncoder untuk menangani ini.

Sekedar memberikan ruang untuk ide:

Saya memiliki masalah yang sama, tetapi terhubung ke Django, yang saya gunakan sebagai backend untuk proyek yang saya gunakan dalam proyek di mana saya menggunakan mpld3.

Saya mencoba membuat serial array numpy dan saya mendapatkan kesalahan ini, saat menggunakan Django 1.6. Saya menurunkan versi ke 1,5 dan berfungsi. Saya menemukan alasannya karena dari 1.6 ke atas, serialisasi dilakukan dengan json, sedangkan dari 1.5 ke bawah, melalui Pickle.

Saya harap ini bisa membantu kalian menemukan masalahnya.

Med vennlig hilsen,
Gerardo de La Riva Espinosa
Hgskolelektor
Høgkolen dan Gjøvik
e-posting: gerardo. [email protected]
Mobil: +47 950 13 322

Pada 19 Juni 2014, pukul 16:56, lvasseur [email protected] menulis:

Halo semua,
Tidak yakin apakah terkait, tetapi saya mendapatkan masalah serupa ketika mencoba memplot grafik seaborn ini: 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: Transformasi campuran belum didukung. Perilaku zoom mungkin tidak berfungsi seperti yang diharapkan.
warnings.warn("Transformasi campuran belum didukung. "
Traceback (panggilan terakhir terakhir):
berkas "", baris 1, di
File "/home/vagrant/graph/local/lib/python2.7/site-packages/mpld3/_display.py", baris 236, di fig_to_html
figure_json=json.dumps(figure_json),
File "/usr/lib/python2.7/json/__init__.py", baris 231, di dump
kembalikan _default_encoder.encode(obj)
File "/usr/lib/python2.7/json/encoder.py", baris 201, dalam encode
potongan = self.iterencode(o, _one_shot=Benar)
File "/usr/lib/python2.7/json/encoder.py", baris 264, di iterencode
kembalikan _iterencode(o, 0)
File "/usr/lib/python2.7/json/encoder.py", baris 178, secara default
angkat TypeError(repr(o) + " bukan JSON serializable")
TypeError: 0 tidak JSON serializable
Masalahnya adalah nomor numpy.int64 digunakan secara internal, dan ini tidak json serializable secara default.
Harus ada pengait di perpustakaan untuk menyediakan json.JSONEncoder untuk menangani ini.


Balas email ini secara langsung atau lihat di GitHub.

untuk diketahui,

    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)

memecahkan masalah di /mpld3/_display.py : fig_to_html

Saya tidak punya waktu untuk mencoba sekarang, tetapi sepertinya ini adalah masalah dan arah yang tepat untuk solusi. Dokumen json.dump membuat saya berpikir bahwa ada solusi yang sedikit lebih ringan dengan opsi default , meskipun pada akhirnya mungkin hanya satu baris lebih pendek. Apakah Anda siap untuk melakukan permintaan tarik?

Saya berharap ini diperbaiki oleh PR #213, tetapi notebook ipython dari posting asli masih tidak berfungsi untuk saya. Bisakah orang lain mencobanya?

Saya akan mencoba ini di beberapa titik

Masih bingung dengan ini... Saya tidak yakin apakah #213 benar-benar memperbaiki sesuatu di sini. Saya dapat membuat serial objek int64 tanpa itu ...

apakah ini terpecahkan?
Sepertinya saya tidak dapat fig_to_html figur yang dihasilkan panda ( saya mendapatkan TypeError: 0 is not JSON serializable ). Gambar dihasilkan dengan baik.
Ketika saya mencoba lagi dengan menggunakan plt.bar saya juga mendapatkan kesalahan jika saya menggunakan yticks dengan string khusus.

Bagaimana menyelesaikan?

Tidak yakin. Tampaknya ada masalah dengan label sumbu yang menjadi versi bilangan bulat yang tidak dapat serial. Jika Anda menemukan sesuatu, beri tahu kami.

Hanya ingin menunjukkan bahwa saya mendapatkan kesalahan ini saat menggunakan

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

tapi tidak dengan

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

Semoga ini membantu.

Sunting: Pada pemeriksaan lebih lanjut, sementara versi terakhir tidak menghasilkan kesalahan, xticks gambar yang dihasilkan tidak benar-benar disetel.

Sunting 2: Buruk saya, baru tahu kutu tidak didukung (#22).

FWIW, menggunakan boxplots dapat mengulangi masalah:

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)

Secara khusus, berikut adalah versi dari 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

untuk Python 3.4.3.

Tambalan yang disarankan oleh

Untuk membuat contoh asli berfungsi, gunakan [float(x) untuk x dalam range(2000,2002)] alih-alih np.arange(2000,2002,1).

Tidak yakin apakah terkait, tetapi saya mendapatkan masalah serupa ketika mencoba memplot grafik seaborn ini: http://www.stanford.edu/~mwaskom/software/seaborn/examples/many_facets.html

Saya mendapatkan kesalahan yang sama saat mencoba mtld3.display(fig) untuk angka barplot seaborn:

TypeError: 0 tidak JSON serializable

Adakah yang bisa membuat plot seaborn dengan mpld3?

Ini tampaknya terjadi karena ada nan dalam nilai data. Jika saya istirahat di _display.py:243nan dengan None di figure_json dict, saya mendapatkan hasil yang diharapkan.

Sunting: di atas sepertinya tidak menyelesaikan masalah (saya sedang menguji di penerjemah debug, di mana itu berhasil tetapi tidak saat menggunakan mpld3).
Jadi, rendering sns.barplot() tidak berfungsi, sementara rendering plt.bar() berfungsi dengan baik. Saya tidak dapat melihat perbedaan angka yang jelas dari kedua plot, tetapi menyediakan tambalan ( https://github.com/mpld3/mpld3/pull/213) memecahkan masalah.

Saya memperbaikinya dengan menambahkan baris

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

ke /mpld3/_display.py: NumpyEncoder

Terima kasih @jaklinger ini berhasil!!!

@jaklinger , Hai, terima kasih atas saran Anda, ini berfungsi dengan baik! Saya hanya ingin mengklarifikasi satu hal - saya mengonversi array numpy ke kamus dan mencoba mengembalikannya tetapi ada kesalahan "float 32 is not json serializable", meskipun tidak ada masalah dengan kamus, mencetak dan memeriksanya. Hanya dengan menggunakan metode tolist() Anda, itu mengubah array menjadi daftar python.
sebelumnya :[100. 0. 0. 0.]
dengan tolist: [100.0, 0.0, 0.0, 0.0, 0.0] dan itu kembali dengan sempurna.
Jadi apa masalahnya sebenarnya? Banyak terima kasih sebelumnya.

@padmaksha18 Saya tidak 100% yakin apa yang Anda maksud dengan

mengonversi array numpy ke kamus

tetapi (singkatnya) tipe numpy dan python tidak sama ( float32 tidak sama dengan float ; an array tidak sama dengan list , dll) dan kelas JSONEncoder hanya 'mengizinkan' tipe python . Jadi... inti dari fungsi ini (yang berisi perbaikan baru) adalah untuk mengubah input obj menjadi setara python .

@jaklinger : Hai Joel, sekali lagi terima kasih banyak. Dengan mengonversi ke kamus, saya hanya bermaksud mengambil dua array seperti itu dan membentuk pasangan nilai kunci, maaf karena tidak menjelaskannya dengan jelas. Terima kasih banyak telah menjelaskan hal ini kepada saya, saya harus mengonversinya ke tipe python asli terlebih dahulu dan itulah masalahnya. Hanya ingin memperjelas satu hal lagi, seperti jika tidak jsonify kamus dan mencoba mengembalikannya apa adanya, apakah kelas jsonencoder akan muncul? Terimakasih banyak!

Apakah halaman ini membantu?
0 / 5 - 0 peringkat

Masalah terkait

sheldonpark picture sheldonpark  ·  7Komentar

arnaudrenaud picture arnaudrenaud  ·  4Komentar

omn14 picture omn14  ·  17Komentar

ledmonster picture ledmonster  ·  4Komentar

pranet picture pranet  ·  6Komentar