D3.js在Jupyter Notebook中

huangapple go评论61阅读模式
英文:

D3.js in JupyterNotebook

问题

我正在尝试在Jupyter Notebook(通过VSCode)上使用D3.js绘制一个交互式网络图。以下是我迄今为止尝试的最佳代码:

import networkx as nx

G = nx.Graph()

G.add_edge(1, 2)
G.add_edge(1, 3)
G.add_edge(2, 3)
G.add_edge(3, 4)
G.add_edge(4, 5)

pos = nx.spring_layout(G)

然后,我按照以下方式构建了HTML:

from IPython.display import display, HTML
html = """
<div id="graph"></div>
<script src="https://d3js.org/d3.v7.min.js"></script>
<script>
var data = %s;

var svg = d3.select("#graph").append("svg")
    .attr("width", 500)
    .attr("height", 500);

var simulation = d3.forceSimulation(data.nodes)
    .force("link", d3.forceLink(data.links).id(function(d) { return d.id; }))
    .force("charge", d3.forceManyBody())
    .force("center", d3.forceCenter(250, 250))
    .on("tick", ticked);

var link = svg.append("g")
    .attr("stroke", "#999")
    .attr("stroke-opacity", 0.6)
    .selectAll("line")
    .data(data.links)
    .join("line")
    .attr("stroke-width", function(d) { return Math.sqrt(d.value); });

var node = svg.append("g")
    .attr("stroke", "#fff")
    .attr("stroke-width", 1.5)
    .selectAll("circle")
    .data(data.nodes)
    .join("circle")
    .attr("r", 5)
    .attr("fill", "#000");

node.append("title")
    .text(function(d) { return d.id; });

function ticked() {
    link
        .attr("x1", function(d) { return d.source.x; })
        .attr("y1", function(d) { return d.source.y; })
        .attr("x2", function(d) { return d.target.x; })
        .attr("y2", function(d) { return d.target.y; });

    node
        .attr("cx", function(d) { return d.x; })
        .attr("cy", function(d) { return d.y; });
}
</script>
""" % nx.node_link_data(G)

最后,我运行了以下代码:

display(HTML(html))

但是图形没有绘制出来(没有任何消息或其他内容)。

我的目标是运行这个笔记本(其中包含多个Python函数)并将其整个转换为HTML文件。但是当我这样做时,HTML中也没有网络图。

感谢您的帮助。

英文:

I'm trying to plot an interactive network with D3.js on Jupyter Notebook (via VSCode).

Here is the best code that I tried so far:

import networkx as nx
    
G = nx.Graph()

G.add_edge(1, 2)
G.add_edge(1, 3)
G.add_edge(2, 3)
G.add_edge(3, 4)
G.add_edge(4, 5)

pos = nx.spring_layout(G)

Then, I build an HTML as follow:

from IPython.display import display, HTML
html = &quot;&quot;&quot;
&lt;div id=&quot;graph&quot;&gt;&lt;/div&gt;
&lt;script src=&quot;https://d3js.org/d3.v7.min.js&quot;&gt;&lt;/script&gt;
&lt;script&gt;
var data = %s;

var svg = d3.select(&quot;#graph&quot;).append(&quot;svg&quot;)
    .attr(&quot;width&quot;, 500)
    .attr(&quot;height&quot;, 500);

var simulation = d3.forceSimulation(data.nodes)
    .force(&quot;link&quot;, d3.forceLink(data.links).id(function(d) { return d.id; }))
    .force(&quot;charge&quot;, d3.forceManyBody())
    .force(&quot;center&quot;, d3.forceCenter(250, 250))
    .on(&quot;tick&quot;, ticked);

var link = svg.append(&quot;g&quot;)
    .attr(&quot;stroke&quot;, &quot;#999&quot;)
    .attr(&quot;stroke-opacity&quot;, 0.6)
    .selectAll(&quot;line&quot;)
    .data(data.links)
    .join(&quot;line&quot;)
    .attr(&quot;stroke-width&quot;, function(d) { return Math.sqrt(d.value); });

var node = svg.append(&quot;g&quot;)
    .attr(&quot;stroke&quot;, &quot;#fff&quot;)
    .attr(&quot;stroke-width&quot;, 1.5)
    .selectAll(&quot;circle&quot;)
    .data(data.nodes)
    .join(&quot;circle&quot;)
    .attr(&quot;r&quot;, 5)
    .attr(&quot;fill&quot;, &quot;#000&quot;);

node.append(&quot;title&quot;)
    .text(function(d) { return d.id; });

function ticked() {
    link
        .attr(&quot;x1&quot;, function(d) { return d.source.x; })
        .attr(&quot;y1&quot;, function(d) { return d.source.y; })
        .attr(&quot;x2&quot;, function(d) { return d.target.x; })
        .attr(&quot;y2&quot;, function(d) { return d.target.y; });

    node
        .attr(&quot;cx&quot;, function(d) { return d.x; })
        .attr(&quot;cy&quot;, function(d) { return d.y; });
}
&lt;/script&gt;
&quot;&quot;&quot; % nx.node_link_data(G)

And, finally, I run the code:

display(HTML(html))

But the graph did not is plotted (without any message or anything else).

My aim is to run this notebook (there are several python functions inside that) and convert it whole into HTML file. When I do that, the HTML did not have the network as well.

Thank you for help

答案1

得分: 1

以下是翻译好的内容:

  • ipydagred3 - "ipywidgets库,用于在JupyterLab中使用dagre-d3绘制有向无环图" - 这看起来非常符合您尝试做的事情。我在Gitter聊天中了解到它,作者说,“在JupyterLab中很难找到一个好的交互式图形查看器,最好的选择似乎是将holoviews附加到networkx。所以我快速编写了一个围绕dagre-d3的包装器”。在那次对话中的这些相关评论也可能对您有帮助,“我以前写过nx_altair,它利用Vega(通过altair)的可视规范来绘制交互式图形。” 和,“我需要一个可以随时间改变的图形(用于调试图形替代),所以最终我包装了cytoscape js https://github.com/Quansight-Labs/metadsl/tree/master/typez/src”。

为什么我说ipydagred3看起来与您的代码尝试匹配。您可以访问ipydagred3存储库并单击'launch binder'。会话启动后,双击左侧文件导航面板中的'docs'目录。然后进入'examples',最后单击example.ipynb以激活打开该笔记本。运行该笔记本的前六个单元格。第六个单元格将在笔记本中呈现小部件。该代码让我想起了您所展示的内容。您会看到您可以运行接下来的几个单元格,小部件视图将得到更新。

英文:

Here's some resources with some details for some related tech I've seen that is meant to play well with Jupyter, placing those I think my be best bets towards workable code for in Jupyter at the top:

  • ipydagred3 - "ipywidgets library for drawing directed acyclic graphs in jupyterlab using dagre-d3" - This looks like it matches what you are trying to do very well. I learned of it in a gitter chat when the author said, "was having trouble finding a good interactive graph viewer in jlab. best bet seemed to be holoviews attached to networkx. so I wrote a quick wrapper around dagre-d3". These related comments in that conversation might also help you, " I wrote nx_altair awhile back, which leverages Vega's (through altair) viz spec to draw interactive graphs." And, " I needed a graph that could change over time, (to debug graph replacements) so I ended up wrapping cytoscape js https://github.com/Quansight-Labs/metadsl/tree/master/typez/src&quot;.

    Why I say ipydagred3 looks to match your code attempt. You can see by going to the ipydagred3 repo and clicking on 'launch binder'. When the session comes up, double-click on the 'docs' directory in the file navigator panel on the left. Then go into 'examples' and finally, click on example.ipynb to open that notebook actively. Run the first six cells of that. The sixth cell will render the widget in the notebook. The code reminded me a bit of what you are showing. You'll see you can run the next few cells and the widget view gets updated.

  • Announcement of 'IPySimulate: Tools to create interactive simulations with IPython and Jupyter' at the Jupyter Discourse Community Forum - "Tools to create interactive simulations with IPython and Jupyter, including a control panel, widgets to adjust parameters at runtime, and dynamic D3.js visualizations."

  • D3 in jupyterlab discussion at Jupyter Discourse Community Forum

huangapple
  • 本文由 发表于 2023年3月9日 20:23:11
  • 转载请务必保留本文链接:https://go.coder-hub.com/75684570.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定