O.r*_*rka 5 python plot graph networkx plotly
我正在研究一个plot.ly包装器,用于改编自https://plot.ly/python/network-graphs/的 networkx图.我无法弄清楚如何根据权重更改每个连接的宽度.权重在attr_dictas中weight.我尝试设置go.Line对象,但它没有工作:(.有任何建议吗?(如果可能的话,链接到教程:)).从我在matplotlib中创建的绘图中附加网络结构的示例.
如何在图中为每个连接设置单独的线宽?
import requests
from ast import literal_eval
import plotly.offline as py
from plotly import graph_objs as go
py.init_notebook_mode(connected=True)
# Import Data
pos = literal_eval(requests.get("https://pastebin.com/raw/P5gv0FXw").text)
df_plot = pd.DataFrame(pos).T
df_plot.columns = list("xy")
edgelist = literal_eval(requests.get("https://pastebin.com/raw/2a8ErW7t").text)
_fig_kws={"figsize":(10,10)}
# Plotting Function
def plot_networkx_plotly(df_plot, pos, edgelist, _fig_kws):
# Nodes
node_trace = go.Scattergl(
x=df_plot["x"],
y=df_plot["y"],
mode="markers",
)
# Edges
edge_trace = go.Scattergl(
x=[],
y=[],
line=[],
mode="lines"
)
for node_A, node_B, attr_dict in edgelist:
xA, yA = pos[node_A]
xB, yB = pos[node_B]
edge_trace["x"] += [xA, xB, None]
edge_trace["y"] += [yA, yB, None]
edge_trace["lines"].append(go.Line(width=attr_dict["weight"],color='#888'))
# Data
data = [node_trace, edge_trace]
layout = {
"width":_fig_kws["figsize"][0]*100,
"height":_fig_kws["figsize"][1]*100,
}
fig = dict(data=data, layout=layout)
py.iplot(fig)
return fig
plot_networkx_plotly(df_plot, pos, edgelist, _fig_kws)
# ---------------------------------------------------------------------------
# PlotlyDictValueError Traceback (most recent call last)
# <ipython-input-72-4a5d0e26a71d> in <module>()
# 46 py.iplot(fig)
# 47 return fig
# ---> 48 plot_networkx_plotly(df_plot, pos, edgelist, _fig_kws)
# <ipython-input-72-4a5d0e26a71d> in plot_networkx_plotly(df_plot, pos, edgelist, _fig_kws)
# 25 y=[],
# 26 line=[],
# ---> 27 mode="lines"
# 28 )
# 29
# ~/anaconda/lib/python3.6/site-packages/plotly/graph_objs/graph_objs.py in __init__(self, *args, **kwargs)
# 375 d = {key: val for key, val in dict(*args, **kwargs).items()}
# 376 for key, val in d.items():
# --> 377 self.__setitem__(key, val, _raise=_raise)
# 378
# 379 def __dir__(self):
# ~/anaconda/lib/python3.6/site-packages/plotly/graph_objs/graph_objs.py in __setitem__(self, key, value, _raise)
# 430
# 431 if self._get_attribute_role(key) == 'object':
# --> 432 value = self._value_to_graph_object(key, value, _raise=_raise)
# 433 if not isinstance(value, (PlotlyDict, PlotlyList)):
# 434 return
# ~/anaconda/lib/python3.6/site-packages/plotly/graph_objs/graph_objs.py in _value_to_graph_object(self, key, value, _raise)
# 535 if _raise:
# 536 path = self._get_path() + (key, )
# --> 537 raise exceptions.PlotlyDictValueError(self, path)
# 538 else:
# 539 return
# PlotlyDictValueError: 'line' has invalid value inside 'scattergl'
# Path To Error: ['line']
# Current path: []
# Current parent object_names: []
# With the current parents, 'line' can be used as follows:
# Under ('figure', 'data', 'scattergl'):
# role: object
Run Code Online (Sandbox Code Playgroud)
我认为问题出在您的代码的以下行中:
edge_trace["lines"].append(go.Line(width=attr_dict["weight"],color='#888'))
Run Code Online (Sandbox Code Playgroud)
尝试用“line”代替“lines”。这是 Plotly API 中有点令人困惑的方面,但在散点图中,模式是复数,而用于更改跟踪属性的参数名称是单数。所以,
trace = go.Scatter(mode = 'markers', marker = dict(...))
trace = go.Scatter(mode = 'lines', line = dict(...))
Run Code Online (Sandbox Code Playgroud)
编辑:好吧,既然我坐下来解决了这个问题,那么问题就不仅仅是“线条”了:
您将line参数视为类似字典的对象列表,而情节则期望它是单个类似字典的对象。构建权重列表,然后line立即将所有权重添加到属性中似乎可行:
edge_trace = go.Scattergl(
x=[],
y=[],
mode="lines"
)
weights = []
for node_A, node_B, attr_dict in edgelist:
xA, yA = pos[node_A]
xB, yB = pos[node_B]
edge_trace["x"] += [xA, xB, None]
edge_trace["y"] += [yA, yB, None]
weights.append(attr_dict["weight"])
edge_trace['line'] = dict(width=weights,color='#888')
Run Code Online (Sandbox Code Playgroud)
此外,您正在节点前面绘制线条,从而阻碍它们。你应该改变
data = [node_trace, edge_trace]
Run Code Online (Sandbox Code Playgroud)
到
data = [edge_trace, node_trace]
Run Code Online (Sandbox Code Playgroud)
以避免这种情况。
| 归档时间: |
|
| 查看次数: |
600 次 |
| 最近记录: |