簡體   English   中英

mpld3.show() 返回類型為 int 的對象不是 JSON 可序列化的

[英]mpld3.show() returns Object of type int is not JSON serializable

我想創建一個網絡,您可以將鼠標懸停在每個標簽上以交互方式閱讀它。

我正在使用 jupyter 實驗室,規格是:選定的 Jupyter 核心包...

IPython          : 7.6.1
ipykernel        : 5.1.1
ipywidgets       : 7.6.5
jupyter_client   : 7.0.6
jupyter_core     : 4.8.1
jupyter_server   : not installed
jupyterlab       : 1.0.2
nbclient         : not installed
nbconvert        : 5.5.0
nbformat         : 4.4.0
notebook         : 6.0.0
qtconsole        : 4.5.1
traitlets        : 4.3.2

當我在 jupyter notebook 中運行這段代碼時:

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

fig, ax = plt.subplots(subplot_kw=dict(axisbg='#EEEEEE'))
N = 100

scatter = ax.scatter(np.random.normal(size=N),
                     np.random.normal(size=N),
                     c=np.random.random(size=N),
                     s=1000 * np.random.random(size=N),
                     alpha=0.3,
                     cmap=plt.cm.jet)
ax.grid(color='white', linestyle='solid')

ax.set_title("Scatter Plot (with tooltips!)", size=20)

labels = ['point {0}'.format(i + 1) for i in range(N)]
tooltip = mpld3.plugins.PointLabelTooltip(scatter, labels=labels)
mpld3.plugins.connect(fig, tooltip)

mpld3.show()

我從這里獲得,一個新窗口打開,帶有交互式標簽,正如預期的那樣,與超鏈接中的示例相同。

我自己的數據是:

index col_A
0     6840
1     6640
2      823
3    57019

index col_B
0     7431
1     5217
2     7431
3    57019

對於網絡,這些是像這樣的節點標簽對:

col_A  col_B
6840   7431
6640   5217
823    7431
57019  57019

所以輸出網絡應該有三個集群:

6840-7431-823
6640-5217
57019-57019

當我運行這段代碼時,它幾乎與上面的示例代碼相同:

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



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

G = nx.from_pandas_edgelist(final_net,'col_A','col_B',['col_A', 'col_B'])
print(final_net['col_A'][0:10])
print(final_net['col_B'][0:10])

edge_labels = nx.get_edge_attributes(G, "Edge_label")
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)
mplcursors.cursor(hover=True)

mpld3.show()

我確實得到了正確的靜態圖像:

在此處輸入圖片說明

但我收到一個錯誤:

TypeError: Object of type int is not JSON serializable

並且網絡不會在我可以與之交互的新窗口中打開(理想情況下,交互網絡無論如何都會保留在 jupyter 中)。

我將對象類型更改為字符串以查看發生了什么:

final_net['col_A'] = pd.to_numeric(final_net['col_A'])
final_net['col_B'] = pd.to_numeric(final_net['col_B'])

隨着輸出:

col_A    int64
col_B    int64

但錯誤仍然相同。 當我刪除最后一行mpld3.show() ,錯誤消失了,所以我只得到一個靜態圖像作為輸出,沒有錯誤,但也沒有交互性。

我按照這里卸載並重新安裝了 conda(保持相同的錯誤),然后我按照這里轉儲到 JSON

通過做:

import json
import numpy as np

data = [[6840, 7431], [6640, 5217], [823, 7431],[57019,57019]]
final_net = pd.DataFrame(data, columns = ['col_A', 'col_B'])

class NumpyEncoder(json.JSONEncoder):
    """ Special json encoder for numpy types """
    def default(self, obj):
        if isinstance(obj, np.integer):
            return int(obj)
        elif isinstance(obj, np.floating):
            return float(obj)
        elif isinstance(obj, np.ndarray):
            return obj.tolist()
        return json.JSONEncoder.default(self, obj)

#dumped = json.dumps(final_net, cls=NumpyEncoder)

#with open(path, 'w') as f:
#    json.dump(dumped, f)
    
final_net['col_A'] = json.dumps(final_net['col_A'],cls=NumpyEncoder)
final_net['col_B'] = json.dumps(final_net['col_B'],cls=NumpyEncoder)

當我轉儲到 json 然后再次重新運行我的網絡代碼時,它輸出:

0    "{\"0\":6840,\"1\":6640,\"2\":823,\"3\":57019}"
1    "{\"0\":6840,\"1\":6640,\"2\":823,\"3\":57019}"
2    "{\"0\":6840,\"1\":6640,\"2\":823,\"3\":57019}"
3    "{\"0\":6840,\"1\":6640,\"2\":823,\"3\":57019}"
Name: Entrez Gene Interactor A, dtype: object
0    "{\"0\":7431,\"1\":5217,\"2\":7431,\"3\":57019}"
1    "{\"0\":7431,\"1\":5217,\"2\":7431,\"3\":57019}"
2    "{\"0\":7431,\"1\":5217,\"2\":7431,\"3\":57019}"
3    "{\"0\":7431,\"1\":5217,\"2\":7431,\"3\":57019}"

而這個形象(這是錯誤的),並沒有交互性。 在此處輸入圖片說明

我想知道是否有人可以告訴我如何編輯我的代碼以使交互功能出現(理想情況下在 jupyter notebook 中,如果不是,則可以在新窗口中打開)。

問題似乎是G.nodes()不是標簽列表。 您可以通過將其轉換為列表( list(G.nodes()) )來獲取節點編號或標簽。

更新版本可能如下所示:

import matplotlib.pyplot as plt
import networkx as nx
import pandas as pd
import numpy as np
import mpld3

final_net = pd.DataFrame({'col_A': [6840, 6640, 823, 57019],
                          'col_B': [7431, 5217, 7431, 57019]})
G = nx.from_pandas_edgelist(final_net, 'col_A', 'col_B', ['col_A', 'col_B'])
print(final_net['col_A'][0:10])
print(final_net['col_B'][0:10])

edge_labels = nx.get_edge_attributes(G, "Edge_label")
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 = list(G.nodes())
tooltip = mpld3.plugins.PointLabelTooltip(scatter, labels=labels)
mpld3.plugins.connect(fig, tooltip)

mpld3.show()

mpld3 與 networkx 圖

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM