Git Product home page Git Product logo

simplegexf's Introduction

Simple GEXF

A simple .gexf parser / writer for python

Notice: This is currently work in progress, and I hope to be able to create documentation in the future when I've settled on the overall structure.

Motivation:

The official pygexf is poorly maintained and almost not documented at all. I needed a simple abstraction layer for the XML format for my project. This project uses xmltodict, which means it's much easier to understand and debug than pygexf which uses lxml. This is a tool for those who'd rather spend their time learning about something more interesting and worthwhile than XML.

Usage:

from simplegexf import Gexf, Edge

gexf = Gexf('tags.gexf')

try:
    graph = gexf.graphs[0]
except IndexError:
    graph = gexf.add_graph(defaultedgetype="directed")

# Define Graph attributes
graph.define_attributes([
    ('description', 'string'),
    ('count', 'integer'),
])

# Define Edge attributes for Graph
graph.define_attributes([
    ('relation_type', 'string'),
], _class='edge')

nodes = {node.id: node for node in graph.nodes}

tags = [
    {
        id: 0,
        name: 'Test tag 1',
        description: 'This is a test tag',
    },
    {
        id: 1,
        name: 'Test tag 2',
        description: 'This is a test tag',
        parents: [0],
    },
    {
        id: 2,
        name: 'Test tag 3',
        description: 'This is a test tag',
        parents: [0, 1],
    }
]

# Create nodes for tags:
for tag in tags:
    try:
        # See if node exists:
        node = nodes[str(tag['id'])]
    except KeyError:
        # Create a new node:
        node = self.graph.add_node(id=str(tag['id']), label=tag['name'])

    # Update node:
    node.set('viz:size', value=10.0)
    node.set('viz:color', r=130, g=130, b=130)

    # Update node attributes:
    for attr in self.graph.node_attributes.keys():
        try:
            node.attributes[attr] = tag[attr]
        except KeyError:
            try:
                del node.attributes[attr]
            except IndexError:
                pass

nodes = {node.id: node for node in graph.nodes}

# Create edges for tags:
for tag in tags:
    try:
        for parent_id in tag['parents']:
            edge = Edge(parent_id, tag['id'])
            graph.edges.append(edge)
            # Attributes are not available before adding edge to graph
            edge.attributes['relation_type'] = 'parents'
    except KeyError:
        pass

graph.sort_nodes(attr='count', reverse=True)

gexf.write()

simplegexf's People

Contributors

demux avatar theclonker avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

simplegexf's Issues

Project restructuring

Should I go for more magic, or less?

Ideas:

from simplegexf import Gexf, Graph, Edge


class MyGraph(simplegexf.Graph):
    defaultedgetype='directed'

    node_attributes = [
        ('name', 'string'),
        ('description', 'string'),
        ('weight', 'integer'),
    ]

    edge_attributes = [
        ('rel_type', 'string'),
    ]


gexf = simplegexf.Gexf('/path/to/file.gexf')

try:
    graph = gexf.graphs[0]
except KeyError:
    graph = MyGraph()
    gexf.graphs.append(graph)

tag_list = [
    {
        'id': 'c6fa996d-8593-484d-b067-69bc828bbeba',
        'name': 'Test Tag',
        'description': "Fairy penguins citylink, east brunswick club trams",
        'weight': 13,
        'parents': [],  # List of UUIDs
    }
    ...
]

# Create Nodes:
for tag in tag_list:
    try:
        # graph.nodes behaves like an OrderedDict, and nodes get mapped by id,
        # so it will throw `KeyError` if the key does not exist:
        node = graph.nodes[tag['id']]
        # or, graph.nodes should behave like a list, and we use a method to assist:
        node = graph.nodes.get(tag['id'])  # As in get_by_id()
    except KeyError:
        node = Node(tag['id'])
        # graph.nodes behaves like an OrderedDict, but also like a list,
        # so we can append.
        graph.nodes.append(node)
        # I'm not sure about this. Maybe it's best if graph.nodes behaves
        # like a list.

    # node.attributes is an OrderedDict, so .update takes a list of tuples:
    node.attributes.update([
        ('name', tag['name']),
        ('description', tag['description']),
        ('weight', tag['weight']),
    ])

# Create Edges:
for tag in tag_list:
    for parent_id in tag.get('parents', []):
        try:
            edge = graph.edges.get(parent_id, tag['id'])
        except KeyError:
            edge = Edge(parent_id, tag['id'])
            graph.edges.push(edge)

        edge.attributes['rel_type'] = 'parents'

Less Python Magic:

from simplegexf import Gexf


gexf = simplegexf.Gexf('/path/to/file.gexf')

try:
    graph = gexf.graphs[0]
except KeyError:
    graph = gexf.create_graph()

graph.define_attributes([
    ('name', 'string'),
    ('description', 'string'),
    ('weight', 'integer'),
])

graph.define_attributes([
    ('rel_type', 'string'),
], _class='edge')

tag_list = [
    {
        'id': 'c6fa996d-8593-484d-b067-69bc828bbeba',
        'name': 'Test Tag',
        'description': "Fairy penguins citylink, east brunswick club trams",
        'weight': 13,
        'parents': [],  # List of UUIDs
    }
    ...
]

# Create Nodes:
for tag in tag_list:
    try:
        node = graph.get_node(tag['id'])
    except KeyError:
        node = graph.create_node(tag['id'])

    # even...
    node = graph.get_or_create_node(tag['id'])

    node.attributes.update([
        ('name', tag['name']),
        ('description', tag['description']),
        ('weight', tag['weight']),
    ])

# Create Edges:
for tag in tag_list:
    for parent_id in tag.get('parents', []):
        try:
            edge = graph.get_edge(parent_id, tag['id'])
        except KeyError:
            edge = graph.create_edge(parent_id, tag['id'])

        # even...
        edge = graph.get_or_create_edge(parent_id, tag['id'])

        edge.attributes['rel_type'] = 'parents'

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.