如何在通过回调添加和删除节点时固定 Dash Cytoscape 中节点的位置?

2024-02-05

我想使用以下示例数据源制作一个带有交互式网络图的 Web 应用程序:

data = {'Source Node': ['a', 'a', 'b', 'b', 'c'],
     'Destination Node': ['b', 'c', 'c', 'd', 'd'],
     'Link': ['likes', 'likes', 'likes', 'likes', 'dislikes']
    }

所需的网络图具有以下标准:

  1. 节点应标有其名称。 (完毕)

  2. 根据“链接”是“喜欢”(绿色)还是“不喜欢”(红色),边缘应具有不同的颜色。 (通过 Networkx 边缘属性完成)

  3. 用户应该可以拖动节点。 (完成 - 首先尝试 Bokeh,然后切换到 Dash Cytoscape 以使其成为可能)

  4. 用户应该能够选择清单中的元素,以便仅查看网络图中的这些元素。 (以不太理想的方式完成,请参阅最后的注释以了解更多详细信息)

  5. 通过清单添加或删除元素时,现有节点应保持在固定位置,但默认情况并非如此,因为每次回调都会创建一个新的网络图。

到目前为止,我制作了一个满足标准 1 到 4 的草稿应用程序。但是,在添加和删除节点时,我没有设法将节点保持在固定位置。在展示我迄今为止拥有的代码后,我将提供更多详细信息。

下面是满足条件 1 到 4 的代码。

# Python v 3.9.13
# Importing libraries
import pandas as pd # v 1.4.4
import numpy as np # v 1.21.5
import networkx as nx # v 2.8.8
import dash_cytoscape as cyto # v 0.2.0
from dash import Dash, html, dcc, Input, Output # v 2.7.0

# Data source
data = {'Source Node': ['a', 'a', 'b', 'b', 'c'],
     'Destination Node': ['b', 'c', 'c', 'd', 'd'],
     'Link': ['likes', 'likes', 'likes', 'likes', 'dislikes']
    }

# Creating a DataFrame using Pandas
df = pd.DataFrame(data)

# Defining lists for dcc.Checklist
list_all_ids = ['a', 'b', 'c', 'd']
default_list_selected_ids = ['a', 'c']


# Creating Dash app
app = Dash(__name__)

app.layout = html.Div(
    [
        dcc.Checklist(list_all_ids, default_list_selected_ids, id='checklist-elements'),
        cyto.Cytoscape(
            id='cytoscape_layout',
            elements=[],
            style={"width": "100%", "height": "400px"},
            layout={"name": "preset"},
            stylesheet=[
                {
                    'selector': 'node',
                    'style': {
                        'content': 'data(label)'
                    }
                },
                {
                    'selector': 'edge',
                    'style': {
                        'line-color': 'data(edge_color)'
                    }
                }
            ]
        )
    ]
)

@app.callback(
    Output('cytoscape_layout', 'elements'),
    Input('checklist-elements', 'value')
)
def update_elements(selected_ids):
    
    # Making a new df
    df_temp = df[df['Source Node'].isin(selected_ids)]
    df_selected = df_temp[df_temp['Destination Node'].isin(selected_ids)]
    # MAKING A NETWORK GRAPH WITH NETWORKX

    # Creating a network graph from the DataFrame
    G = nx.from_pandas_edgelist(df_selected, 'Source Node', 'Destination Node', edge_attr='Link')

    # Setting edge colors (green or red based on whether the nodes "like" or "dislike" each other)
    list_colors = ['red' if a['Link']=='dislikes' else 'green' for u, v, a in G.edges(data=True)]
    dict_colors = {k:v for (k,v) in zip(G.edges(), list_colors)}
    nx.set_edge_attributes(G, dict_colors, 'edge_color')

    pos = nx.spring_layout(G, seed = 100)

    
    # CONVERTING NETWORKX GRAPH TO CYTOSCAPE FORMAT - Big thanks to Robert Alexander and canbax
    # https://stackoverflow.com/questions/71428375/dash-cytoscape-from-python-networks-graph-not-honouring-the-nodes-coordinates
    
    # Initial conversion
    cy = nx.cytoscape_data(G)

    # Replacing dictionary key 'value' with 'label' in the nodes list of cy
    for n in cy["elements"]["nodes"]:
        for k, v in n.items():
            v["label"] = v.pop("value")

    # Adding positions of nodes from pos
    SCALING_FACTOR = 100
    for n, p in zip(cy["elements"]["nodes"], pos.values()):
        n["position"] = {"x": int(p[0] * SCALING_FACTOR), "y": int(p[1] * SCALING_FACTOR)}

    elements=cy["elements"]["nodes"] + cy["elements"]["edges"]
    
    return elements

if __name__ == "__main__":
    app.run_server()

正如您所看到的,如果您运行代码并使用清单,每次单击复选框时,节点都会获得一个新位置。这是有道理的,因为每次都会创建一个新的网络图。但是,我希望当您选择或取消选择其他节点时,节点坚持到一个位置。为了实现这一目标,我尝试了两种完全不同的方法,但均不成功:

第一种方法:

  • 而不是使用pos = nx.spring_layout(G, seed = 100),我创建了一个预定义位置的字典(np.array()对于位置,因为它是在中找到的类型pos = nx.spring_layout(G, seed = 100)(以下)。我在定义应用程序之前放置了此代码。
dict_fixed_pos = {'a': np.array([-0.5, -0.5]),
 'b': np.array([-0.5, 0.5]),
 'c': np.array([0.5, 0.5]),
 'd': np.array([0.5, -0.5])}
  • 我替换:
for n, p in zip(cy["elements"]["nodes"], pos.values()):
        n["position"] = {"x": int(p[0] * SCALING_FACTOR), "y": int(p[1] * SCALING_FACTOR)}

with:

for n in cy["elements"]["nodes"]:
        if n['data']['id'] in selected_ids:
            n['position'] = dict_fixed_pos[n['data']['id']]

有了这个,我希望每次创建网络图时,每个给定节点都能从dict_fixed_pos。但相反,所有节点都重叠在同一位置。看起来 Cytoscape 无法识别指定的位置,但我不知道如何解决这个问题。任何想法?

第二种方法:

  • Instead of a callback that adds and removes elements, I tried to see if I could create a callback that changes the style of the nodes. So, the nodes would be invisible by default, and the selected nodes would be set as visible. As a test to see if this would be possible, I made the following changes in the callback function:
    • 我删除了重新定义数据框的部分,以便使用原始的 df 。
    • 循环内部:
for n, p in zip(cy["elements"]["nodes"], pos.values()):
        n["position"] = {"x": int(p[0] * SCALING_FACTOR), "y": int(p[1] * SCALING_FACTOR)}

我添加了以下代码以添加密钥'selected'到每个节点。的价值'selected'将会'yes' or 'no'根据是否对应'id'被选择于dcc.Checklist:

if n['data']['id'] in selected_ids:
            n['selected'] = "yes"
        else:
            n['selected'] = "no"

我在样式表中添加了以下内容cyto.Cytoscape()(只是更改背景颜色而不是可见性,因为我还没有弄清楚如何更改可见性(刚刚看到这是可能的):

{
                    'selector': '[selected = "yes"]',
                    'style': {
                        'background-color': '#FF4136'
                    }

然而,这些变化导致all节点成为blue(代替selected节点成为red).

那么,您认为这两种方法中的一种在进行一些更改后是否可行?或者你有什么完全不同的建议吗?预先感谢您抽出时间。

请注意第四个标准,能够根据清单中的选择添加或删除节点:最初,我想在应用程序启动时创建一次 df、网络图和元素列表;然后,在回调函数内,根据清单值,将从元素列表中选择要显示的元素。因为这不起作用,所以我决定在回调函数中从头开始重新创建网络图。然而,这远非理想,因此如果有人知道如何仅更新回调函数中的元素列表,我们也将非常感谢您的帮助。


None

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

如何在通过回调添加和删除节点时固定 Dash Cytoscape 中节点的位置? 的相关文章

随机推荐

  • 将参数传递给槽

    我想用一堆 QActions 和 QMenus 覆盖 mouseReleaseEvent connect action1 SIGNAL triggered this SLOT onStepIncreased connect action5
  • Parallel.For 与 BigInteger 计算输出不同于 For 循环

    我有以下循环运行从 base95 到 base10 的转换 我正在处理几千位数字 因此需要 BigIntegers inst是base95字符串 Parallel For 0 inst Length x gt result BigInteg
  • 如何在web.xml和log4j.properties中配置log4j输出文件路径?

    我开发了一个网络应用程序 可以在其中注册员工 My web xml
  • 从 Jackson 获取未知字段列表

    我有一个 JSON 架构和一个与该架构匹配的 json 字符串 但它可能有一些额外的字段 如果我不添加这些字段 杰克逊将抛出异常objectMapper configure DeserializationConfig Feature FAI
  • PDO 数据库访问 WHERE title = $title

    我正在尝试学习使用 PDO 而不是 MySQLi 进行数据库访问 但在从数据库中选择数据时遇到问题 我想使用 STH DBH gt query SELECT FROM ratings WHERE title title ORDER BY d
  • ios 5 上的 NSDateFormatter - 还有其他使用方法吗?

    我有一段代码在 iOS 4 3 5 之前一直有效 现在在 iOS 5 中不起作用 Example of date I m using Mon 31 Oct 2011 15 57 55 BRST NSDateFormatter formatt
  • 当数据集更改时,在闪亮的应用程序中动态显示列名称会闪烁错误

    我有一个闪亮的应用程序 我希望允许用户根据一组上传的文件选择数据集 然后指定要从所选数据集中显示的列 如果我选择某些列然后切换数据集 则会闪烁错误并输出到控制台 指出在应用程序切换数据集并正确显示之前所选列未知 然而 在我的完整应用程序中
  • Font Awesome 带有 easyAutocomplete 插件

    我有一个表单 我想在其中显示输入文本字段并在同一行上提交 输入文本字段有两个 FontAwesome 图标 我想在文本字段内显示它们 当我不使用简单的自动完成插件时 我可以根据需要设置表单样式 但是当我激活轻松自动完成 http easya
  • 如何从 Firebase 中推送的数据中获取价值?

    在我的 firebase 中 我存储了问题及其答案 每个答案都有一个 id 它是从 push 获得的 但我无法显示已回答问题的所有用户的列表 请帮忙 这是代码 ListView listView ArrayList
  • 如何组合两个 LPCWSTR?

    我有两个变量LPCWSTRs 我想创建一个新变量 该变量将具有第一个和第二个变量的值 我尝试过这个 但没有成功 LPCWSTR d L sd LPCWSTR f L f LPCWSTR df d f 当我尝试这样做时 我收到此错误 1 In
  • myisam 表上的外键替代方案?

    我正在开发一个需要使用外键的网站 但是我已经搜索遍了 共享主机不支持innoDB 我正在使用 MyISAM 引擎 有没有使用外键的替代方法 我需要的 table image image id PK table ratings rating
  • 使用 KNN 分类器进行数字识别之前的预处理

    现在我正在尝试使用 OpenCV 创建数字识别系统 WEB上有很多文章和例子 甚至在堆栈溢出 https stackoverflow com questions 9413216 simple digit recognition ocr in
  • 无法安装 Subversive SVN Team Provider

    当我尝试从 Eclipse Marketplace 或其项目站点 安装 Subversive SVN Team Provider 时 出现以下错误 The following solutions are not available Subv
  • WordPress 按标签查询相关帖子

    我正在尝试查询与 WordPress 中当前查看的帖子具有相同标签的帖子列表 我认为如果我可以查询当前帖子的标签列表 将其传递到一个变量中 然后将该变量传递到 query posts 参数中 它就可以完成工作 它似乎适用于帖子中的标签之一
  • CSS 填充简写声明中的反斜杠

    Qq com 网站有一个规则集 其中有两个填充声明 这看起来有点奇怪 我的问题是 11px 0部分做什么 这与覆盖第一个填充声明有关吗 我理解斜线在以下情况下的使用 css 样式声明中的 正斜杠 https stackoverflow co
  • 在 pandas to_csv 方法中保留列顺序

    pandas 的 to csv 方法不保留列的顺序 它选择按字母顺序排列 CSV 中的列 这是一个错误 已被报告并应该在版本 0 11 0 中得到纠正 我有0 18 0 import pandas as pd df pd DataFrame
  • 屏幕更新效果

    我一直在测量代码执行时间 以衡量本地执行脚本和在服务器上执行脚本之间的差异 有一次我忘记禁用screen updating庆幸的是 在更详细地考虑之前 我对闪光灯不敏感 当我第一次开始使用时VBA我一直认为它只是被使用 这样就不会吓到最终用
  • bash:jstat:找不到命令

    我想使用 gc 实用程序来分析我的 Cassandra 数据库的垃圾收集 但是当我运行 jstat 命令时 输出显示 bash jstat command not found 我搜索并发现 jstat 位于 JAVA HOME bin 但我
  • 为什么我无法向 Hotmail 发送电子邮件?

    这是我的代码 boundary sha1 whatever headers MIME Version 1 0 r n headers From Domainname email protected cdn cgi l email prote
  • 如何在通过回调添加和删除节点时固定 Dash Cytoscape 中节点的位置?

    我想使用以下示例数据源制作一个带有交互式网络图的 Web 应用程序 data Source Node a a b b c Destination Node b c c d d Link likes likes likes likes dis