[Python] how to make graph-tool sfdp_layout behave deterministically for consistent plotting?

Discussão em 'Python' iniciado por Stack, Setembro 7, 2025.

  1. Stack

    Stack Membro Participativo

    I am using graph-tool's sfdp_layout to plot a graphml file. sfdp_layout is nondeterministic, so each time I plot it generates a slightly different layout. this would be fine except that I'm plotting the graph through matplotlib, and want to adjust the sizes of markers and edges. When the layout positions change even slightly, the same values for marker/edge sizes gives wildly different results. To avoid this, how can I make sfdp_layout deterministic for a given graph?

    below is a minimal example that reproduces the problem. Plotting this graphml file (https://pastebin.com/QsHJG7pi) with:

    pos = gt.sfdp_layout(g, r=0.2, init_step=0.1)


    generates large edges and vertices:

    big edges/vertices

    while plotting with ``init_step=None``` - which changes the layout - produces small edges and vertices, even when the size settings don't change:

    small edges/vertices

    To make sfdp_layout deterministic, I tried setting the seeds on both the python and graph-tool sides:

    np.random.seed(seed)
    random.seed(seed)
    gt.seed_rng(seed)


    but the plotting is still nondeterministic.

    Full code:

    import graph_tool.all as gt
    import matplotlib.pyplot as plt
    import matplotlib.backends.backend_pdf as pdf_backend
    import numpy as np

    def graphml_to_pdf_with_plt(graphml_path, pdf_path):
    plt.switch_backend("cairo")
    # set seeds, but this won't make sfdp_layout deterministic
    seed = 42
    np.random.seed(seed)
    random.seed(seed)
    gt.seed_rng(seed)
    g = gt.load_graph(graphml_path)
    # generates large nodes/edges
    #pos = gt.sfdp_layout(g, r=0.2, init_step=0.1)
    # generates small nodes/edges
    pos = gt.sfdp_layout(g, r=0.2, init_step=None)
    fig, ax = plt.subplots(figsize=(12, 11.5))
    vcolor = g.new_vertex_property("vector<double>")
    for v in g.vertices():
    vcolor[v] = [0.0, 0.0, 0.0, 0.7]
    # node border color (set to transparent)
    vborder = g.new_vertex_property("vector<double>")
    for v in g.vertices():
    vborder[v] = [0, 0, 0, 0]
    ecolor = g.new_edge_property("vector<double>")
    for e in g.edges():
    ecolor[e] = [0.5, 0.5, 0.5, 0.7]
    w = gt.graph_draw(g, pos,
    output_size=(500, 500),
    vertex_size=2.0,
    edge_pen_width=0.2,
    edge_marker_size=3.5,
    vertex_fill_color=vcolor,
    vertex_color=vborder,
    edge_color=ecolor,
    ink_scale=0.2,
    fit_view=True,
    fit_view_ink=True,
    mplfig=fig)
    w.fit_view()
    fig.savefig(pdf_path)


    graphml_path = "simple_test.graphml"
    graphml_to_pdf_with_plt(graphml_path, "test.pdf")


    I tried setting the seed on the gt side and expected it to make sfdp_layout deterministic for a given graph, but it didn't work. the seed doesn't seem to matter.

    Continue reading...

Compartilhe esta Página