可视化

为了可视化图投影,建议使用 Graph Visualization for Python (neo4j-viz) 库。该库可在 Snowflake 官方 Anaconda 包仓库中获取,可在存储过程、函数和笔记本中使用。

可视化是交互式的,支持缩放、平移、移动节点以及悬停节点和关系以查看其属性等功能。

The Cora dataset
图 1. Cora 数据集的可视化

语法

本节介绍从 Snowflake 表生成交互式图可视化的语法。

neo4j_viz 库提供了名为 from_snowflake 的方法,用于从 Snowflake 表创建 VisualizationGraph 对象。然后可以使用其 render 方法进行渲染,生成 HTML/JavaScript。

from_snowflake 方法接受两个必需的位置参数

  • 用于连接 Snowflake 的 snowflake.snowpark.Session 对象,以及

  • Neo4j Snowflake 图形分析应用程序定义的项目配置。

从 Snowflake 表创建可视化图
from neo4j_viz.snowflake import from_snowflake

from snowflake.snowpark.context import get_active_session
session = get_active_session()

viz_graph = from_snowflake(
    session,
    {
        'nodeTables': [...],
        'relationshipTables': {...}
    }
)

通过 from_snowflake 返回的 VisualizationGraph 对象提供了多种在渲染前配置可视化的方法。例如,VisualizationGraph.color_nodes 可根据特定属性更改节点的颜色。还有其他配置方法,例如更改节点大小和固定节点位置。请参阅 documentation 了解所有可用选项。

一旦按需配置好 VisualizationGraph 对象,就可以使用 render 方法进行渲染。该方法仅接受一个可视化配置参数,可用于设置渲染图的尺寸以及布局。请参阅 documentation 获取所有可用选项。

渲染可视化图
html_object = viz_graph.render(
    {...}  # Visualization configuration
)

html_object 变量现在包含用于所需图可视化的 HTML/JavaScript 字符串。对于 Snowflake 笔记本中的 streamlit 应用,可使用 streamlit 库中的 components.html 方法渲染该字符串。

使用 streamlit 渲染 HTML/JavaScript 字符串
import streamlit.components.v1 as components
components.html(
    html_object,
    height=600  # Height in pixels
)

示例

在本例中,我们将在 Snowflake 笔记本中可视化一个小型图,展示一小群人及其喜爱的乐器。

设置图

我们将使用 SQL 笔记本单元格创建所需的三个表:一个存放人物的节点表、一个存放乐器的节点表,以及一个表示人物对乐器“LIKES”(喜欢)关系的关系表。

CREATE OR REPLACE TABLE EXAMPLE_DB.DATA_SCHEMA.PERSONS (NODEID VARCHAR);
INSERT INTO EXAMPLE_DB.DATA_SCHEMA.PERSONS VALUES
  ('Alice'),
  ('Bob'),
  ('Carol'),
  ('Dave'),
  ('Eve');

CREATE OR REPLACE TABLE EXAMPLE_DB.DATA_SCHEMA.INSTRUMENTS (NODEID VARCHAR);
INSERT INTO EXAMPLE_DB.DATA_SCHEMA.INSTRUMENTS VALUES
  ('Guitar'),
  ('Synthesizer'),
  ('Bongos'),
  ('Trumpet');

CREATE OR REPLACE TABLE EXAMPLE_DB.DATA_SCHEMA.LIKES (SOURCENODEID VARCHAR, TARGETNODEID VARCHAR);
INSERT INTO EXAMPLE_DB.DATA_SCHEMA.LIKES VALUES
  ('Alice', 'Guitar'),
  ('Alice', 'Synthesizer'),
  ('Alice', 'Bongos'),
  ('Bob',   'Guitar'),
  ('Bob',   'Synthesizer'),
  ('Carol', 'Bongos'),
  ('Dave',  'Guitar'),
  ('Dave',  'Trumpet'),
  ('Dave',  'Bongos');

可视化图投影

现在已有这些表后,我们即可开始可视化它们。我们在 SQL 笔记本单元格中调用 from_snowflake 方法。请注意,必须在笔记本环境中选中 neo4j_viz 库才能工作。

from neo4j_viz.snowflake import from_snowflake
from snowflake.snowpark.context import get_active_session

session = get_active_session()

viz_graph = from_snowflake(
    session,
    {
        'nodeTables': ['EXAMPLE_DB.DATA_SCHEMA.PERSONS', 'EXAMPLE_DB.DATA_SCHEMA.INSTRUMENTS'],
        'relationshipTables': {
            'EXAMPLE_DB.DATA_SCHEMA.LIKES': {
                'sourceTable': 'EXAMPLE_DB.DATA_SCHEMA.PERSONS',
                'targetTable': 'EXAMPLE_DB.DATA_SCHEMA.INSTRUMENTS'
            }
        }
    }
)

html_object = viz_graph.render()

import streamlit.components.v1 as components

components.html(html_object.data, height=600)

输出

Rendering the HTML

图形渲染良好,我们可以看到两种节点类型 PERSONSINSTRUMENTS 被不同地着色和标注(依据默认设置)。关系则以带有 “LIKES” 标注的箭头呈现。

我们可以进行放大、缩小、平移、移动节点,并在节点和关系上悬停查看属性。右上角的按钮还能进行缩放,并可对图进行 PNG 快照。

接下来,我们希望对图执行一些图算法并可视化结果。为此需确保应用有权限访问前面创建的表。

授予应用访问表的权限

-- Use a role with granting privileges
USE ROLE ACCOUNTADMIN;
USE DATABASE EXAMPLE_DB;

CREATE OR REPLACE DATABASE ROLE MY_DB_ROLE;
GRANT USAGE ON DATABASE EXAMPLE_DB TO DATABASE ROLE MY_DB_ROLE;
GRANT USAGE ON SCHEMA EXAMPLE_DB.DATA_SCHEMA TO DATABASE ROLE MY_DB_ROLE;
GRANT SELECT ON ALL TABLES IN SCHEMA EXAMPLE_DB.DATA_SCHEMA TO DATABASE ROLE MY_DB_ROLE;
GRANT SELECT ON ALL VIEWS IN SCHEMA EXAMPLE_DB.DATA_SCHEMA TO DATABASE ROLE MY_DB_ROLE;
GRANT CREATE TABLE ON SCHEMA EXAMPLE_DB.DATA_SCHEMA TO DATABASE ROLE MY_DB_ROLE;
-- Change the app name below if you don't have the default one
GRANT DATABASE ROLE MY_DB_ROLE TO Neo4j_Graph_Analytics;

现在,我们可以使用 Neo4j 图形分析应用对图运行图算法。

按组件自定义节点颜色

首先,我们运行弱连接组件(WCC)算法以识别图中的连通组件。我们希望将结果用于在可视化中根据组件为节点着色。如果您使用笔记本,请在 SQL 笔记本单元格中执行以下内容。

-- Change the app name here if you don't have the default one
CALL Neo4j_Graph_Analytics.graph.wcc('CPU_X64_XS', {
    'project': {
        'nodeTables': ['EXAMPLE_DB.DATA_SCHEMA.PERSONS', 'EXAMPLE_DB.DATA_SCHEMA.INSTRUMENTS'],
        'relationshipTables': {
            'EXAMPLE_DB.DATA_SCHEMA.LIKES': {
                'sourceTable': 'EXAMPLE_DB.DATA_SCHEMA.PERSONS',
                'targetTable': 'EXAMPLE_DB.DATA_SCHEMA.INSTRUMENTS',
                'orientation': 'NATURAL'
            }
        }
    },
    'compute': {},
    'write': [{
        'nodeLabel': 'PERSONS',
        'outputTable': 'EXAMPLE_DB.DATA_SCHEMA.PERSONS_COMPONENTS'
    },
    {
        'nodeLabel': 'INSTRUMENTS',
        'outputTable': 'EXAMPLE_DB.DATA_SCHEMA.INSTRUMENTS_COMPONENTS'
    }]
});

现在我们已经获得 WCC 算法的输出表,可以再次可视化图,这次使用新表作为节点表。同时我们将配置可视化,使节点颜色基于 “COMPONENT” 属性。

from neo4j_viz.snowflake import from_snowflake
from snowflake.snowpark.context import get_active_session

session = get_active_session()

project_config = {
    'nodeTables': ['EXAMPLE_DB.DATA_SCHEMA.PERSONS_COMPONENTS', 'EXAMPLE_DB.DATA_SCHEMA.INSTRUMENTS_COMPONENTS'],
    'relationshipTables': {
      'EXAMPLE_DB.DATA_SCHEMA.LIKES': {
        'sourceTable': 'EXAMPLE_DB.DATA_SCHEMA.PERSONS_COMPONENTS',
        'targetTable': 'EXAMPLE_DB.DATA_SCHEMA.INSTRUMENTS_COMPONENTS',
        'orientation': 'NATURAL'
      }
    }
  }

viz_graph = from_snowflake(session, project_config)

# Color nodes according to their component
viz_graph.color_nodes(property='COMPONENT', override=True)

rendered = viz_graph.render()

import streamlit.components.v1 as components

components.html(rendered.data, height=600)

输出

Rendering the HTML with component coloring

可以看到节点现在根据其在图中的连通组件被着色。

按 PageRank 自定义节点大小

接下来,我们希望计算图中节点的 PageRank,并据此在可视化中调整节点大小。我们先在 SQL 笔记本单元格中运行 PageRank 算法。

-- Change the app name here if you don't have the default one
CALL Neo4j_Graph_Analytics.graph.pagerank('CPU_X64_XS', {
    'project': {
        'nodeTables': ['EXAMPLE_DB.DATA_SCHEMA.PERSONS', 'EXAMPLE_DB.DATA_SCHEMA.INSTRUMENTS'],
        'relationshipTables': {
            'EXAMPLE_DB.DATA_SCHEMA.LIKES': {
                'sourceTable': 'EXAMPLE_DB.DATA_SCHEMA.PERSONS',
                'targetTable': 'EXAMPLE_DB.DATA_SCHEMA.INSTRUMENTS',
                'orientation': 'NATURAL'
            }
        }
    },
    'compute': {},
    'write': [{
        'nodeLabel': 'PERSONS',
        'outputTable': 'EXAMPLE_DB.DATA_SCHEMA.PERSONS_CENTRALITY'
    },
    {
        'nodeLabel': 'INSTRUMENTS',
        'outputTable': 'EXAMPLE_DB.DATA_SCHEMA.INSTRUMENTS_CENTRALITY'
    }]
});

现在得到 PageRank 结果后,我们可以再次可视化图,这次使用新表作为节点表,并将可视化配置为根据 “PAGERANK” 属性调整节点大小。

from neo4j_viz.snowflake import from_snowflake
from snowflake.snowpark.context import get_active_session
session = get_active_session()

project_config = {
    'nodeTables': ['EXAMPLE_DB.DATA_SCHEMA.PERSONS_CENTRALITY', 'EXAMPLE_DB.DATA_SCHEMA.INSTRUMENTS_CENTRALITY'],
    'relationshipTables': {
      'EXAMPLE_DB.DATA_SCHEMA.LIKES': {
        'sourceTable': 'EXAMPLE_DB.DATA_SCHEMA.PERSONS_CENTRALITY',
        'targetTable': 'EXAMPLE_DB.DATA_SCHEMA.INSTRUMENTS_CENTRALITY',
        'orientation': 'NATURAL'
      }
    }
  }

viz_graph = from_snowflake(session, project_config)

# Map each node id to its PAGERANK value as input for node resizing
sizes = {node.id: node.properties['PAGERANK'] for node in viz_graph.nodes}

# Resize nodes according to their page rank
viz_graph.resize_nodes(sizes=sizes, node_radius_min_max=(10, 100))

# Caption nodes with their original id property
for node in viz_graph.nodes:
    node.caption = node.properties["SNOWFLAKEID"]

# Render the graph
rendered = viz_graph.render()

import streamlit.components.v1 as components

components.html(rendered.data, height=600)

输出

Rendering the HTML with PageRank sizing

可以看到节点现在根据其在图中的 PageRank 大小进行缩放。邦戈的中心性高于吉他,谁会想到呢 :)

性能注意事项

from_snowflake 方法的性能取决于待可视化图的规模和复杂度以及运行机器的配置。

render 方法的配置接收参数 max_allowed_nodes,默认值为 10,000,因为渲染大型图可能会慢且无响应。选择不同的渲染器也能有所帮助,详见 documentation