def group_people_js(request, mode="egograph", output="full"):
    """Return Belfast Group network graph data as JSON, for use with
    :meth:`group_people`.

    Optionally filter
    the data by minimum degree, if min_degree is specified as a url parameter.
    When generating the node and link data, nodes are annotated with
    degree, in degree, out degree, betweenness centrality, and eigenvector
    centrality if available.  (In/out degree is only available for directed
    graphs.)

    :param mode: egograph: network information for a one- or two-degree
        egograph centered around the Belfast Group; groupsheet-model:
        alternate network graph based on the Group sheets themselves
    :param output: full: node and link data; adjacency: adjacency matrix,
        used for generating chord diagram
    """

    if mode == "egograph":
        degree = request.GET.get("degree", 1)
        extra_opts = {}
        try:
            degree = int(degree)
            # currently only support 1 or 2 degree
            degree = max(1, min(degree, 2))
            # NOTE: degree 2 graph is large enough that it *must* be filtered
            # to be sensible and usable on the webpage;
            # by trial & error, I found a minimum degree of 5 to be reasonable
            if degree == 2:
                extra_opts["min_degree"] = 5
        except ValueError:
            # if a value is passed that can't be converted to int, fallback to 1
            degree = 1

        belfast_group = RdfOrganization(network_data().copy(), BELFAST_GROUP_URI)
        graph = belfast_group.ego_graph(radius=degree, types=["Person", "Organization"], **extra_opts)

        # annotate nodes in graph with degree
        # FIXME: not a directional graph; in/out degree not available
        graph = annotate_graph(
            graph, fields=["degree", "in_degree", "out_degree", "betweenness_centrality", "eigenvector_centrality"]
        )

    elif mode == "groupsheet-model":
        graph = gexf.read_gexf(settings.GEXF_DATA["bg1"])
        graph = annotate_graph(
            graph, fields=["degree", "betweenness_centrality", "eigenvector_centrality"]  #'in_degree', 'out_degree',
        )

    if output == "full":
        data = json_graph.node_link_data(graph)
    if output == "adjacency":
        # adjacency matrix for generating chord diagram
        matrix = nx.convert_matrix.to_numpy_matrix(graph)

        # NOTE: this also works, but as of networx 1.9 requires scipy
        # matrix = nx.linalg.graphmatrix.adjacency_matrix(graph)
        data = matrix.tolist()

    return HttpResponse(json.dumps(data), content_type="application/json")
Beispiel #2
0
def plot_decompose(r):

    ego_node = df_decompose.query(
        f'iteration == {r.iteration+1}')['tag'].iloc[0]
    print(r.iteration, ego_node, sp[ego_node])
    g_node = gexf.read_gexf(r.filename)
    # sp1 = layout.kamada_kawai_layout(g_node)
    nx.draw(g_node,
            pos=sp,
            node_color='#0C84B6',
            node_size=5,
            with_labels=False)
    nx.draw_networkx_edges(g_node, pos=sp, alpha=0.04, edge_color='#D8E7F5')

    plt.text(sp[ego_node][0],
             sp[ego_node][1],
             r.tag,
             fontsize=8,
             bbox={
                 'facecolor': 'white',
                 'edgecolor': 'none',
                 'alpha': 0.5
             })
    nx.draw_networkx_nodes(g_node,
                           pos=sp,
                           nodelist=[ego_node],
                           node_size=10,
                           node_color='r')

    plt.axis('off')
    # plt.show()
    plt.savefig('images/' + r.filename.replace('.gexf', '.png'), dpi=500)
    plt.show()
def gexf_content(request, mode):
    """Make network data available as GEXF files for download and use in
    tools like Gephi."""
    if mode == "all":
        graph = network_data()
    elif mode == "group-people":
        # filtered graph of people/places/organizations used for
        # first BG network graph displayed on the site
        # - same data used in :meth:`full_js`
        graph = _network_graph()
    elif mode == "groupsheets":
        graph = gexf.read_gexf(settings.GEXF_DATA["bg1"])

    buf = StringIO()
    gexf.write_gexf(graph, buf)
    response = HttpResponse(buf.getvalue(), content_type="application/gexf+xml")
    response["Content-Disposition"] = "attachment; filename=belfastgroup-%s.gexf" % mode
    return response
def egograph_node_info(request, id):
    """HTML snippet to provide information about a node in the egograph.
    Intended to be loaded and displayed via AJAX.

    Some overlap with :meth:`belfast.network.views.node_info`.
    """

    # id is the person to whom this node is connected
    uri = local_uri(reverse("people:profile", args=[id]), request)
    g = rdf_data()
    ego_person = RdfPerson(g, rdflib.URIRef(uri))

    # NOTE: some overlap here with networks node_info view

    # id param is the node we want information
    node_id = request.GET.get("id", None)
    if node_id is None:
        raise Http404

    node_uri = rdflib.URIRef(node_id)
    # TODO: better to get relations from gexf or rdf ?
    graph = gexf.read_gexf(settings.GEXF_DATA["full"])
    node = graph.node[node_id]
    context = {"node": node}

    if node.get("type", None) == "Person":
        # init rdf person
        person = RdfPerson(rdf_data(), rdflib.URIRef(node_id))
        context["person"] = person

    # determine relation between node and ego-center
    rels = set(g.predicates(ego_person.identifier, node_uri))
    # TODO: may want to display other relationships?

    # special case: if "mentions", should be a poem; find for display/link
    if rdfns.SCHEMA_ORG.mentions in rels:
        txts = set(g.subjects(rdfns.SCHEMA_ORG.mentions, node_uri)) - set([ego_person.identifier])
        if txts:
            poems = [RdfPoem(g, p) for p in txts]
            # explicitly skip any non-poems, just in case
            context["poems"] = [p for p in poems if rdfns.FREEBASE["book/poem"] in p.rdf_types]

    return render(request, "network/node_info.html", context)
def node_info(request):
    """Return an HTML snippet with brief information about a node in the
    network (e.g., name, number of Group sheets, link to profile page
    if there is one).  Intended to be called via AJAX and displayed with
    the network graphs.

    Expects a url parameter ``id`` with the node identifier.
    """
    node_id = request.GET.get("id", None)
    # if no id is specified, 404
    if node_id is None:
        raise Http404
    # TODO: better to get from gexf or rdf ?
    graph = gexf.read_gexf(settings.GEXF_DATA["full"])
    node = graph.node[node_id]
    context = {"node": node}
    if node.get("type", None) == "Person":
        # init rdf person
        person = RdfPerson(rdf_data(), rdflib.URIRef(node_id))
        context["person"] = person
    # TODO: handle other types? location, organization
    return render(request, "network/node_info.html", context)
def load_graph(filepath):
    return gexf.read_gexf(filepath)
Beispiel #7
0
# %%
import networkx as nx
# from networkx.algorithms import centrality
from networkx.readwrite import gexf
import pandas as pd
import matplotlib.pyplot as plt
from networkx.drawing import layout
## https://networkx.github.io/documentation/networkx-1.10/reference/generated/networkx.drawing.nx_agraph.graphviz_layout.html

# %%
print('start')
G = gexf.read_gexf('3mj/subgraph--1-start.gexf')
print('generate layout')
sp = layout.kamada_kawai_layout(G)

degrees = pd.DataFrame(dict(G.degree).items(), columns=['tag', 'degree'])

print(nx.__version__)
print('before')
print(nx.info(G))

nodes_zero_degree = (degrees.query('degree == 0')['tag'].to_list())
G.remove_nodes_from(nodes_zero_degree)

print('after')
print(nx.info(G))

# %%
df_decompose = pd.read_csv('3mj/decomposed_3mj.csv')[[
    'iteration', 'tag', 'filename'
]]
Beispiel #8
0
# %%
import networkx as nx
from networkx.algorithms import centrality
from networkx.algorithms import components
from networkx.readwrite import gexf
import pandas as pd
import tqdm
# import matplotlib.pyplot as plt
# import scipy


# %%
G = gexf.read_gexf('data/outputs/tags-tags.gexf')
print(nx.__version__)
print(nx.info(G))

# %%


def df_from_betweeness(inG):
    print(f'calculate betweenness, network of size {inG.order()}')
    temp_betweenness = centrality.betweenness_centrality(inG)
    return pd.DataFrame(
        temp_betweenness.items(),
        columns=['tag', 'betweenness']).sort_values('betweenness', ascending=False)

# %%
# calc betweenness for the first time and subgraph to remove nodes that have 0 betweeness


df_betweenness = df_from_betweeness(G)
Beispiel #9
0
import networkx as nx
from networkx.readwrite import gexf
from networkx.readwrite import json_graph
import json

G = gexf.read_gexf("static/data/math3.gexf")
# with open("static/data/middle_school_extend.json", "r") as read_file:
#     data = json.load(read_file)
# G = json_graph.node_link_graph(data)
print(nx.info(G))
# G.add_node('test1', modular=1, Degree=0, viz={'size': 50}, label='test1')
# G.remove_node('test')
print(G.nodes['Circle'])
# print(G.nodes['test1'])
print(nx.info(G))
# G = gexf.write_gexf(G, "static/data/middle_school_extend.gexf")
data = json_graph.node_link_data(G)
with open("static/data/middle_school_3.json", "w") as write_file:
    json.dump(data, write_file)
def network_data():
    global _NX_GRAPH
    if _NX_GRAPH is None:
        _NX_GRAPH = gexf.read_gexf(settings.GEXF_DATA['full'])
    return _NX_GRAPH