在Python中可视化RDFLIB图形

8

我是RDFLIB在Python中的新手。我在这里找到了创建图形的示例。有什么最简单的方法可以可视化由此代码创建的图形吗?

import rdflib
# Now we create a graph, a representaiton of the ontology
g = rdflib.Graph()

# Now define the key words that we will use (the edge weights of the graph)
has_border_with = rdflib.URIRef('http://www.example.org/has_border_with')
located_in = rdflib.URIRef('http://www.example.org/located_in')

# define the things - base level objects that will be the nodes
# In this case first we have countries
germany = rdflib.URIRef('http://www.example.org/country1')
france = rdflib.URIRef('http://www.example.org/country2')
china = rdflib.URIRef('http://www.example.org/country3')
mongolia = rdflib.URIRef('http://www.example.org/country4')

# then we have continents
europa = rdflib.URIRef('http://www.example.org/part1')
asia = rdflib.URIRef('http://www.example.org/part2')

# Having defined the things and the edge weights, now assemble the graph
g.add((germany,has_border_with,france))
g.add((china,has_border_with,mongolia))
g.add((germany,located_in,europa))
g.add((france,located_in,europa))
g.add((china,located_in,asia))
g.add((mongolia,located_in,asia))

我看到rdflib包有一个工具组件,其中有一个名为rdfs2dot的函数。我如何使用该函数显示带有RDF图的绘图?

2
我看了一下,但没有找到完整的解决方案。我发现rdfs2dot是一个命令行工具:你必须先导出你的图形 g.serialize("world.rdf"),然后将其转换为dot语法:rdfs2dot world.rdf > world.dot,然后使用任何允许绘制dot图形的工具。例如xdot xdot world.dot。由于某种原因,rdfs2dot生成了一个空图。根据Graph.serialize的文档,rdf应该是默认格式,因此这里可能存在一个错误或者rdfs2dot中存在一个错误。也许可以在github上查看开放的票据,或者发布一个新问题。 - Emilien
谢谢!这很有道理。所以你需要先导出图形,然后在命令提示符中运行一个命令来创建图形dot文件。 - MadProgrammer
2个回答

15

使用此问题中的提示:https://www.researchgate.net/post/Is_there_any_open_source_RDF_graph_converter,我将RDF图转换为Networkx图并使用Networkx / Matplotlib绘图工具进行了绘制。

import rdflib
from rdflib.extras.external_graph_libs import rdflib_to_networkx_multidigraph
import networkx as nx
import matplotlib.pyplot as plt

url = 'https://www.w3.org/TeamSubmission/turtle/tests/test-30.ttl'

g = rdflib.Graph()
result = g.parse(url, format='turtle')

G = rdflib_to_networkx_multidigraph(result)

# Plot Networkx instance of RDF Graph
pos = nx.spring_layout(G, scale=2)
edge_labels = nx.get_edge_attributes(G, 'r')
nx.draw_networkx_edge_labels(G, pos, edge_labels=edge_labels)
nx.draw(G, with_labels=True)

#if not in interactive mode for 
plt.show()

为了可视化大型RDF图形,样式可能需要一些微调;-)


有趣的是,你的回答比问题新了几年。我想知道这段时间内发生了什么变化或改进。 - MadProgrammer
从RDFLib GitHub的历史记录来看,似乎rdflib.extras.external_graph_libs.rdflib_to_networkx_multidigraph在你提出问题时已经可用了。你的意思是说你认为现在应该有更好的解决方案吗? - Tom Hemmes
2
这行代码 result = g.parse(url, 'ttl') 对我来说不起作用。格式参数没有被识别,rdflib 尝试将其解析为 rdf/xml。我必须写入 "format" 关键字,并且使用 "turtle" 而不是 "ttl" 才能使其正常工作。result = g.parse(url, format='turtle') - Asahiko
我将边标签从另一个字典中加入,需要使用nx.draw(G, pos, with_labels=True)按位置绘制它们。 - Lostefra
@TomHemmes,你知道有没有针对大型图表的交互式图表解决方案吗? - Karl 17302

15

正如你建议的那样,我可以使用rdf2dot为您的RDF图制作一张图片。然而,我对该库并不完全满意,因为它不会为字面量创建节点。这是我的代码:

!pip install pydotplus
!pip install graphviz

import io
import pydotplus
from IPython.display import display, Image
from rdflib.tools.rdf2dot import rdf2dot

def visualize(g):
    stream = io.StringIO()
    rdf2dot(g, stream, opts = {display})
    dg = pydotplus.graph_from_dot_data(stream.getvalue())
    png = dg.create_png()
    display(Image(png))

visualize(g)

给出以下结果:输入图像描述


听起来很不错!您介意分享如何使用独立的TTL或(如果可能)SPARQL端点复制此结果吗? - K3it4r0
1
我不确定你的意思。您可以以任何方式加载图形。以下是一个使用标准RDF介绍中的RDF片段的小例子。如果您首先将ttl数据加载到字符串中,例如变量ttlstring,则可以按以下方式获取图形:from rdflib import Graph, URIRef, Literal g = Graph() g.parse(data=ttlstring, format='turtle')然后按上述步骤进行。抱歉,我无法在此处获取任何代码格式或新行。 - Christian Wartena
@ChristianWartena - 这是一个绝妙的答案!- 我今天之前从未遇到过如此优雅的解决方案 - 真是太棒了! - Thomas Kimber
@ChristianWartena 你知道针对大型图表的任何交互式图表解决方案吗? - Karl 17302

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接