使用 matplotlib 设置网络中的动态节点形状

2023-12-29

第一次在这里发帖,请大家多多包涵。 :)

我正在尝试在 Networkx 中绘制不同类型的字符网络,并希望为每种类型设置不同的节点形状。例如,我希望角色是圆形,生物是三角形等。我已经尝试了几个小时来解决这个问题并进行了广泛的搜索,但我还没有找到一种方法来实现这一点,除了为每种类型的字符设置不同的node_lists并分别渲染它们,这似乎违反直觉。

问题是我无法从内部访问 node_shape 字典值:

nx.draw_networkx_nodes(G, pos) 

我尝试了多种解决方案,包括尝试访问节点属性、创建外部字典或列表并从调用中访问它、设置列表理解或迭代器,但似乎没有任何效果。

我要么传递一个列表(该列表是批量提取的)、一个字典(该函数无法对其进行散列),要么传递一个列表的实例,例如shape_list.pop(0),在这种情况下,该函数仅采用第一个值并将其应用于所有节点。

我可以通过创建一个单独的node_colors列表来设置颜色,该列表由函数迭代,甚至尝试创建一个字典,以便node_shape由node_color触发,但这也不起作用。

我希望使用该代码作为使用 Python 3.4 和 Django 1.8 开发的 Web 应用程序的附加组件,因此 Graphviz 不是一个选择。

预先感谢您提供任何帮助或参考备用库。

这是我的代码:

import json
import requests
import networkx as nx
import matplotlib.pyplot as plt

personas = 'http://story-chronicles.herokuapp.com/storyobjects/'
target = requests.get(personas)
x = target.json()

story_objects = {}
labels = {}
node_colors = []

for character in x:
    name = character["name"]
    story = character["story"]
    c_type = character["c_type"]
    story_objects[name] = {}
    story_objects[name]['name'] = name
    story_objects[name]['story'] = story
    story_objects[name]['c_type'] = c_type
    story_objects[name]['to_relationships'] = []
    if character['c_type'] == "Character":
        story_objects[name]['node_shape'] = 'o'
        story_objects[name]['node_color'] = 'r'
    elif character['c_type'] == "Organization":
        story_objects[name]['node_shape'] = 'h'
        story_objects[name]['node_color'] = 'b'
    elif character['c_type'] == "Creature":
        story_objects[name]['node_shape'] = '^'
        story_objects[name]['node_color'] = 'g'
    elif character['c_type'] == "Force":
        story_objects[name]['node_shape'] = 'v'
        story_objects[name]['node_color'] = 'c'
    elif character['c_type'] == "Thing":
        story_objects[name]['node_shape'] = 's'
        story_objects[name]['node_color'] = 'y'

    for relationship in character["to_relationships"]:
        break_1 = relationship.find(">>")
        break_2 = relationship.find("weight:")
        sub_1 = relationship[0:break_1].strip()
        context = relationship[break_1:break_2]
        weight = relationship[break_2+8:-1]
        story_objects[name]['to_relationships'].append([sub_1, context, weight])

G=nx.MultiDiGraph()

for sub in story_objects:
    s = story_objects[sub]
    if s['story'] == "http://story-chronicles.herokuapp.com/story/1/":
        G.add_node(s['name'], node_shape=s['node_shape'])
        labels[s['name']] = s['name']

        node_colors.append(s['node_color'])

        print("***", s['name'], "***", s['c_type'])
        print("details:", s['node_color'], s['node_shape'])
        for i in s['to_relationships']:
            print('target:', i[0])
            print('context:', i[1])
            print('weight:', i[2])
            G.add_edge(s['name'], i[0], weight=int(i[2]))
        print("")

node_shapes=nx.get_node_attributes(G, 'node_shape') # Latest attempt at getting this to work
node_shapes = [v for k,v in node_shapes.items()]

pos=nx.spring_layout(G)
G.degree(weight=weight)

nx.draw_networkx_nodes(G, pos, node_color=node_colors, node_shape=node_shapes.pop(0)) # <--- This is where I'm having problems
nx.draw_networkx_edges(G, pos)
nx.draw_networkx_labels(G, pos, labels)

plt.show()

恐怕这必须使用多次传递来完成。

主要思想是使用一个layout http://networkx.lanl.gov/reference/drawing.html#module-networkx.drawing.layout获取节点的位置,然后使用绘制网络x节点 http://networkx.lanl.gov/reference/generated/networkx.drawing.nx_pylab.draw_networkx_nodes.html反复为n不同类别的节点。

例如:

import networkx
import pylab

#Build a graph (Node attribute 's' determines the node shape here)
G = networkx.Graph()
G.add_node(0, s="^", b=1)
G.add_node(1, s="^", b=2)

G.add_node(2, s="o", b=3)
G.add_node(3, s="o", b=4)

G.add_node(4, s="v", b=5)
G.add_node(5, s="v", b=6)

networkx.add_path(G, [0,2,5])
networkx.add_path(G, [1,4,3,0])
networkx.add_path(G, [2,4,0,5])

#Drawing the graph
#First obtain the node positions using one of the layouts
nodePos = networkx.layout.spring_layout(G)

#The rest of the code here attempts to automate the whole process by
#first determining how many different node classes (according to
#attribute 's') exist in the node set and then repeatedly calling 
#draw_networkx_node for each. Perhaps this part can be optimised further.

#Get all distinct node classes according to the node shape attribute
nodeShapes = set((aShape[1]["s"] for aShape in G.nodes(data = True)))

#For each node class...
for aShape in nodeShapes:
    #...filter and draw the subset of nodes with the same symbol in the positions that are now known through the use of the layout.
    networkx.draw_networkx_nodes(G,nodePos,node_shape = aShape, nodelist = [sNode[0] for sNode in filter(lambda x: x[1]["s"]==aShape,G.nodes(data = True))])

#Finally, draw the edges between the nodes
networkx.draw_networkx_edges(G,nodePos)

#And show the final result
pylab.show()

最终结果看起来像这样:

希望这可以帮助。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 matplotlib 设置网络中的动态节点形状 的相关文章

随机推荐

  • VS 2017 中缺少 ASP.NET Core 2 模板

    I m using VS 2017 Community Edition I ve installed NET Core 2 SDK from here 当我跑步时dotnet version我收到如下回复 但我看不到ASP NET Core
  • 为什么每次创建新视图模型时不调用视图构造函数?

    我正在将 WPF 与模型 视图 视图模型模式一起使用 我有一个 ResultsView 和 ResultsViewModel 它们的连接方式如下
  • Angular 5:装饰器中不支持函数调用

    我正在从 Angular 应用程序构建 PWA 运行时出现以下错误ng build prod ERROR in app app module ts 108 64 Error during template compile of AppMod
  • 不允许远程表值函数调用

    我怎样才能做到这一点 我正在从远程链接服务器运行表值函数 我尝试在这 4 部分命名中不添加锁定 但仍然遇到相同的错误 我使用 mssql 2008 select from 110 10 10 100 testdbname dbo ufn g
  • 如何将 Micrometer 与 @WebMvcTest 连接起来

    我正在尝试测试 Spring Boot 2 3 Controller通过 Actuator Prometheus 执行指标 WebMvcTest 不幸的是 这在 NPE 中失败了 可能是因为测试中不存在 Micrometer Prometh
  • 如何使用 Visual Studio 2015(企业版)构建 boost 版本 1.58.0

    我喜欢使用 新的 Visual Studio 2015 企业版 构建 boost 1 58 0 过去我是按以下方式进行的 从以下位置下载 boost 1 58 0www boost org http www boost org 提取文件 例
  • HTTPServletRequest.getInputStream() 总是接收空行

    客户端 public List
  • Sproutcore 和 Ember 之间的区别

    在 Ember 从 sproutcore 分叉之前 我就选择了 sproutcore 作为框架 我不确定该走哪条路 而且对碎片化造成的努力明显稀释感到有点沮丧 因为这很少会带来更好的事情 Sproutcore 2 0 现在的 Ember 的
  • NDB:对查询结果进行排序

    在 App Engine NDB 中 我正在查询具有重复属性的实体 我想按表示该属性的数组的长度对结果进行排序 我希望我能做什么 Entity query order len Entity repeatedProp 您需要添加一个ndb I
  • gcloud 命令突然根本不起作用

    All gcloud命令突然给出这个错误 错误 gcloud 加载失败 没有名为 google appengine ext 的模块 这通常表明您的 gcloud 安装或 你的Python解释器有问题 请验证以下是否是有效的 Python 2
  • 如何在 Clojure 中使用 definterface?

    Clojure 1 2 0 似乎有一个definterface形式 显然是为了创建 Java 接口 有些人建议使用它 例如 一个答案这个数字运算问题 https stackoverflow com questions 3124344 clo
  • 当 xsl 本身第一页就足够时避免第二页

    我已经找到了问题的解决方案 要感谢你们所有人 因为如果没有你们及时的解决方案和建议 这是不可能实现和解决的 非常感谢 这个问题的解决方案已经实现 非常感谢 要解决您的问题 请将以下所有内容保留在单个表中并将其添加到表标题中 参考您的 xsl
  • JavaScript 正则表达式捕获小数点的重复部分

    寻找最佳方法来获取具有可能重复的小数部分的任意数字 并发现重复部分 如果存在 最终 我需要用上划线符号 使用 css 文本装饰或 MathML mline 来装饰数字 所以我还需要知道重复开始的索引 所以我需要正则表达式来得到 或者可以在算
  • 无法将有序数据写入 Spark 中的镶木地板

    我正在使用 Apache Spark 生成镶木地板文件 我可以按日期对它们进行分区 没有任何问题 但在内部我似乎无法按正确的顺序排列数据 在处理过程中顺序似乎丢失了 这意味着镶木地板元数据不正确 具体来说 我想确保镶木地板行组反映排序顺序
  • 将回归结果输出到 R 中的数据帧中

    我想知道是否有任何命令可以将 lm 模型的结果输出到 R 中的数据帧中 就像 SAS 中的 outest 一样 有任何想法吗 我正在运行多个模型 我希望结果如下所示 Model alpha Beta Rsquared F df model0
  • 为什么 BigQuery 加载作业统计信息会返回查询信息?

    我们有一些加载作业 可以从 GCS 中获取文件 并将它们加载到 BigQuery 中进行分析 我们使用JobConfigurationLoad class https developers google com resources api
  • Android:将sqlite数据库内容加载到webview

    我有一个sqlite我有一个要加载的内容的数据库webview 如我所愿从数据库中选择并在网页视图中显示 有什么办法可以做到吗 public class TataworatYawmeeh extends Activity WebView w
  • 共享内存与 Go 通道通信

    Go 的口号之一是不要通过共享内存进行通信 相反 通过通信来共享内存 http golang org doc effective go html concurrency 我想知道 Go 是否允许在同一台机器上运行的两个不同的 Go 编译的二
  • Jupyter python3笔记本无法识别pandas

    我正在使用 Jupyter 笔记本并选择了 Python 3 在单元格的第一行我输入 import pandas as pd 我从笔记本中得到的错误是 ImportError 没有名为 pandas 的模块 如何将pandas安装到jupy
  • 使用 matplotlib 设置网络中的动态节点形状

    第一次在这里发帖 请大家多多包涵 我正在尝试在 Networkx 中绘制不同类型的字符网络 并希望为每种类型设置不同的节点形状 例如 我希望角色是圆形 生物是三角形等 我已经尝试了几个小时来解决这个问题并进行了广泛的搜索 但我还没有找到一种