Пример #1
0
    def _forceAtlas2Layout_2(self, G: nx.Graph, iterations: int):
        """
        Uses this implementation: https://pypi.org/project/fa2l/
        """

        t_start = time.time()
        pos = force_atlas2_layout(G, iterations=iterations,
                                  pos_list=None,
                                  node_masses=None,
                                  # Hubs attract less and are pushed to the borders
                                  outbound_attraction_distribution=False,
                                  # Makes clusters more tight
                                  lin_log_mode=False,
                                  # Prevent overlaping
                                  prevent_overlapping=True,
                                  edge_weight_influence=1.0,

                                  # Lower gives less speed and more precision
                                  jitter_tolerance=0.2,
                                  # Allows larger graphs
                                  barnes_hut_optimize=True,
                                  barnes_hut_theta=0.5,

                                  # Amount of repulsion
                                  scaling_ratio=0.2,
                                  strong_gravity_mode=False,
                                  # Attracts nodes to the center
                                  gravity=0.5
                                  )
        duration = time.time() - t_start
        print('Generation with {} iterations took {} seconds.'.format(iterations, round(duration, 2)))

        return pos
Пример #2
0
def main():
    if len(sys.argv) < 3:
        sys.exit('usage: %s < input gexf > < output gexf >' % sys.argv[0])

    infile = sys.argv[1]

    G = nx.read_gexf(infile)

    print(G.nodes(data=True))

    G = max(nx.weakly_connected_component_subgraphs(G), key=len)

    #log.info("drawing layout...")
    pos = force_atlas2_layout(G,
                              iterations=50,
                              pos_list=None,
                              node_masses=None,
                              outbound_attraction_distribution=False,
                              lin_log_mode=False,
                              prevent_overlapping=False,
                              edge_weight_influence=1.0,
                              jitter_tolerance=1.0,
                              barnes_hut_optimize=True,
                              barnes_hut_theta=0.5,
                              scaling_ratio=20,
                              strong_gravity_mode=False,
                              multithread=False,
                              gravity=1.0)

    nodes = G.nodes()

    data_nodes = G.nodes(data=True)
    node_colors = [
        '#FF0000' if n[1]['partisan_retweet'] == 'right' else '#999999'
        for n in data_nodes
    ]

    size_field = 'simple_tweet_count'
    max_node_size = 3000
    max_node_val = max([n[1][size_field] for n in data_nodes])
    node_sizes = [
        max_node_size * (n[1][size_field] / max_node_val) for n in data_nodes
    ]

    node_labels = dict((n[0], n[1]['label']) for n in data_nodes)

    pyplot.figure(1, figsize=(24, 16))
    nx.draw_networkx_nodes(G,
                           pos,
                           nodelist=nodes,
                           node_color=node_colors,
                           node_size=node_sizes)
    nx.draw_networkx_labels(G, pos, nodelist=nodes, labels=node_labels)

    pyplot.show()
Пример #3
0
def extract_correct_scale(G, node_sizes, min_scale, max_scale):
    """ 
    Extracts the balanced scale that ensures none of the largest k nodes are neither overlapping nor too far away
    from each other.
    

    
    
    """

    first = min_scale
    last = max_scale
    found = False
    iteration = 0

    while first <= last and not found:

        scale = (first + last) / 2
        print("iteration : " + str(iteration))
        print("current range : " + str((first, last)))
        print("current scale : " + str(scale))

        pos = force_atlas2_layout(G,
                                  iterations=50,
                                  pos_list=None,
                                  node_masses=None,
                                  outbound_attraction_distribution=True,
                                  lin_log_mode=True,
                                  prevent_overlapping=True,
                                  edge_weight_influence=1.0,
                                  jitter_tolerance=1.0,
                                  barnes_hut_optimize=True,
                                  barnes_hut_theta=0.5,
                                  scaling_ratio=scale,
                                  strong_gravity_mode=False,
                                  multithread=False,
                                  gravity=1.0)

        node_overlap = top_k_node_overlap(G, pos, node_sizes)
        node_too_far = has_node_apart(G, pos, node_sizes)

        print("node_overlap is " + str(node_overlap))
        print("node_too_far is " + str(node_too_far))

        if node_overlap == False and node_too_far == False:
            found = True
            return (found, scale, pos)
        else:
            if node_overlap == True:
                first = scale + 1
            else:
                last = scale - 1
        iteration = iteration + 1
    return (found)
Пример #4
0
def main():
    if len(sys.argv) < 2:
        sys.exit('usage: %s < input gexf' % sys.argv[0])

    # Input Graph file

    infile = sys.argv[1]

    G = nx.read_gexf(infile)

    # extract the largest weakly connected component and convert to undirected for fa2l

    G = max(nx.weakly_connected_component_subgraphs(G),
            key=len).to_undirected()

    # set parameters

    colormap = {
        'null': 'lightgray',
        'partisan_2012_conservative': 'r',
        'partisan_2012_liberal': 'b',
        'partisan_2012_libertarian': 'y'
    }
    color_field = "partisan_code"
    size_field = 'inlink_count'
    filter_field = "inlink_count"
    label_field = "label"
    num_labels = 20  # number of labels to visualize
    k = 100  # number of nodes to visualize

    # If the size of Graph > 1000 nodes, set G to the subgraph containing largest 1000 nodes to get the layout

    if len(G.nodes()) > 1000:
        G = filter_graph(G, filter_by=filter_field, top=1000).to_undirected()

    # extract the positions

    pos = force_atlas2_layout(G,
                              iterations=50,
                              pos_list=None,
                              node_masses=None,
                              outbound_attraction_distribution=True,
                              lin_log_mode=True,
                              prevent_overlapping=True,
                              edge_weight_influence=1.0,
                              jitter_tolerance=1.0,
                              barnes_hut_optimize=True,
                              barnes_hut_theta=0.5,
                              scaling_ratio=38,
                              strong_gravity_mode=False,
                              multithread=False,
                              gravity=1.0)

    print("Extracted the positions")
    print(pos)

    # Extract top 500 nodes for visualization
    top_k_subgraph = filter_graph(G, filter_by=filter_field,
                                  top=k).to_undirected()

    # Set visual attributes

    node_colors = set_node_color(top_k_subgraph,
                                 color_by=color_field,
                                 colormap=colormap)
    node_sizes = set_node_size(top_k_subgraph,
                               size_field="inlink_count",
                               min_size=0.1,
                               max_size=800)
    node_labels = set_node_label(top_k_subgraph, label=label_field)
    subgraph_pos = get_subgraph_pos(top_k_subgraph, pos)
    edge_colors = edgecolor_by_source(top_k_subgraph, node_colors)

    print("Drawing the visualization")

    # Get specific labels

    subset_label_nodes = sorted(zip(top_k_subgraph.nodes(), node_sizes),
                                key=lambda x: x[1],
                                reverse=True)[0:num_labels]
    subset_labels = {n[0]: node_labels[n[0]] for n in subset_label_nodes}

    # plot the visualization

    fig = plt.figure(figsize=(10, 10), dpi=100)
    ax = fig.add_subplot(111)
    #ax.set(xlim=[0.0, 1.0], ylim=[0.0, 1.0], title='Network Viz')

    # Draw the nodes, edges, labels separately

    nodes = nx.draw_networkx_nodes(top_k_subgraph,
                                   pos=subgraph_pos,
                                   node_size=node_sizes,
                                   node_color=node_colors,
                                   alpha=.7)
    edges = nx.draw_networkx_edges(top_k_subgraph,
                                   pos=subgraph_pos,
                                   edge_color=edge_colors,
                                   alpha=0.01)
    labels = nx.draw_networkx_labels(top_k_subgraph,
                                     pos=subgraph_pos,
                                     labels=subset_labels,
                                     font_size=8)

    # Adjust label overlapping

    x_pos = [v[0] for k, v in subgraph_pos.items()]
    y_pos = [v[1] for k, v in subgraph_pos.items()]
    adjust_text(texts=list(labels.values()),
                x=x_pos,
                y=y_pos,
                arrowprops=dict(arrowstyle='->', color='lightgray'))

    # Declutter visualization

    #ax.axis("off");

    # save the plot

    plt.savefig("1.png")

    # Show the plot
    plt.show()
Пример #5
0
def draw_forceatlas2_network(G,
                             pos=None,
                             fa2l_iterations=50,
                             fa2l_scaling_ratio=38,
                             scale="auto",
                             num_labels=None,
                             node_list=None,
                             node_color='red',
                             color_by=None,
                             colormap=None,
                             node_size=10,
                             size_field=None,
                             min_size=0.1,
                             max_size=100,
                             with_labels=False,
                             label_field=None,
                             filter_by=None,
                             top=None,
                             adjust_labels=True,
                             node_opacity=1,
                             edge_opacity=0.05,
                             font_size=8,
                             font_color='k',
                             font_family='sans-serif',
                             filename="untitled.png",
                             title=None,
                             edge_color="lightgray",
                             edge_color_by_source=False,
                             figsize=(10, 10),
                             fig_dpi=100,
                             **kwargs):
    """ Main function for drawing graph.

    The function has sensible defaults. If no scale is provided scale for the graph is set automatically. 
    If no pos is given then force atlas 2 layout is used. Other parameters can be described below can be 
    used to customize different aspects of the visualization. 

    See Notes section for dependencies. 

    Check README for examples.


    Parameters
    ----------
    G : nx.Graph

        A networkx graph.

    pos : dict or None. optional. default None.

        pos containing positions for the graph generated by some network layout algorithm. 

        If None, force_atlas2_layout function from fa2l package is used with default parameters to generate 
        the layout for the graph. To use with user given parameters for the force_atlas2_layout, calculate
        pos outside draw function and then pass to the draw function.

        Pos can also be calculated with  any other network layout algorithms like nx.spring_layout(G) 
        and passed to the draw function. 

    fa2l_iterations : int, optional. Default 50..

        number of times to run the default force atlas 2 layout algorithm from fa2l package.

    fa2l_scaling_ratio : float, optional. Default 38.

        How much repulsion you want. More makes a more sparse graph.

    scale : "auto" or float or int. optional. default "auto".

        Used for scaling the graph automatically.Also used for expanding and contracting the graph.

        If "auto", then scale is set automatically. see : mediaviz.scaling.get_auto_scale(...) for how
        scale is set. If given a float or int, positions are scaled according to the number. 

        For example, scale = 2 will expand the graph to twice of its current size while scale = 0.5 will 
        contract the graph to half of its original size. 

        When scaling graph node sizes are not changed, only the relative positions are changed. 

        For example, after doubling a position (2,4) will become (4,8).

    num_labels : int, optional. default None.

        Number of nodes to label sorted by the node size. 

        Recommended to use only with varying node sizes.

        If all node sizes are equal it will just return the nodes from G.nodes() in the same order.

    node_list : list. optional, default None.
        list of nodes to draw. if None and there's no filtering done all nodes are drawn.

    node_color : str or list. default 'red'.

        Multiple variations are allowed. 

        node_color can be color name like "r","b" or hex code in string format.

        node_color can also be a list of colors like ["r","b"...] or ["#FFFFFF","#..."...]. 

        If node_colors are being passed then color_by and colormap should be None(their defaults)

    color_by : node attribute. optional. Default None.

        categorical node attribute to color the nodes by. 

        If color by is given, a colormap dictionary must also be provided.

        Example : if "gender" in graph node attribute, then color_by = "gender" and 
        colormap = {"M":'b',"F":'r'}

    colormap : dict, optional. Default None.

        dictionaries containing color assignment for each value of the categorical node attribute in color_by.

        Assumes color_by is a categorical node_attribute like "gender" or "partition" or "country". 

        colormap is then a dictionary that assigns color for each unique value of that categorical node 
        attribute. 

        Example : If there's two unique values "M" and "F" in "gender" node attribute, then 
        color_by = "gender" and colormap = {"M":'b',"F":'r'}.

    node_size : int or float or list. Default 10.

        Multiple values are supported.
        
        int or float value can be provided to make all node sizes same.

        list of node sizes can also be passed.

        if node_size is given, size_field should not be used. Default of size_field is None.

    size_field : str, optional. Default None.

        Node attribute to resize the nodes by. Must be numeric node attribute.

        If given node sizes are resized to [min_size, max_size] using set_node_size from utils module.

    min_size : float, optional. Default 0.1

        Minimum size for the nodes.

    max_size : float , optional. Default : 100.

        maximum size for the nodes

    with_labels: bool, optional. Default False.

        Whether to show the labels or not. If label_field is not provided node names are used.

    filter_by : str, optional. Default None.
         
         Numeric Node attribute to filter the graph by. If filter_by is given, top must be provided. 

        Filter_by filters the graph to draw only the top k nodes. 

        For example, if filter_by = "inlink_count" and top = 100, the graph is filtered to
        the subgraph containing the top 100 nodes sorted by inlink count and only the subgraph 
        is drawn.

    top : int, optional. Default None.

        Number of largest nodes to keep after filtering using filter_by.

    label_field : str, optional. Default None.

        Node attribute to label the nodes by.

    adjust_labels : bool, optional. Default True.

        If True, Adjust Text package is used for adjusting the labels to prevent label overlap.

        Label texts are iteratively adjusted until there's no overlap.

        See : https://github.com/Phlya/adjustText for details. 

    node_opacity : float. Default 1

        Node alpha.
    
    edge_opacity : float.Default 0.05.

        Edge alpha.

    font_size : int, optional. Default 8.
        
        Label font size.

    font_color : str, optional. Default 'k'

        Label font color. 

    font_family : str. optional. Default 'sans-serif'

        Label font family.

    filename : str, optional. Default "untitled.png"

        File name to save the figure by. 
        See fname from https://matplotlib.org/api/_as_gen/matplotlib.pyplot.savefig.html

    title : str, optional. Default None.

        Plt title.

    edge_color_by_source : bool, optional. Default False.

        If true, edge colors are same as the source node for the edge. If edge_color is given, then 
        edge_color_by_source should be set to default False.

    figsize : tuple, optional. Default : (10,10)
        figure size.

    fig_dpi : float, optional. Default : 100. 
        See https://matplotlib.org/api/figure_api.html for details.


    """
    if node_list:
        G = nx.subgraph(node_list)

    if type(G) == nx.DiGraph:
        G = max(nx.weakly_connected_component_subgraphs(G),
                key=len).to_undirected()

    if pos is None:
        pos = force_atlas2_layout(G,
                                  iterations=fa2l_iterations,
                                  pos_list=None,
                                  node_masses=None,
                                  outbound_attraction_distribution=False,
                                  lin_log_mode=False,
                                  prevent_overlapping=False,
                                  edge_weight_influence=1.0,
                                  jitter_tolerance=1.0,
                                  barnes_hut_optimize=True,
                                  barnes_hut_theta=1.0,
                                  scaling_ratio=fa2l_scaling_ratio,
                                  strong_gravity_mode=False,
                                  multithread=False,
                                  gravity=1.0)

    if scale == "auto":
        if size_field:
            original_node_sizes = dict(
                zip(
                    G.nodes(),
                    set_node_size(G,
                                  size_field=size_field,
                                  min_size=min_size,
                                  max_size=max_size)))
        elif type(node_size) == int or type(node_size) == float:
            original_node_sizes = dict(
                zip(G.nodes(), [node_size] * len(G.nodes())))
        else:
            original_node_sizes = dict(zip(G.nodes(), node_size))
        scale = get_auto_scale(G, pos, original_node_sizes, k=20)
        print("scale is " + str(scale))
        pos = scale_layout(pos, scale)
    elif scale:
        pos = scale_layout(pos, scale)

    if with_labels is True and num_labels is None:
        num_labels = len(G.nodes())

    if filter_by:
        G = filter_graph(G, filter_by=filter_by, top=top)
        pos = get_subgraph_pos(G, pos)

    if color_by:
        node_color = set_node_color(G, color_by=color_by, colormap=colormap)

    if size_field:
        node_size = set_node_size(G,
                                  size_field=size_field,
                                  min_size=min_size,
                                  max_size=max_size)
    elif type(node_size) == int or type(node_size) == float:
        node_size = [node_size] * len(G.nodes())

    if edge_color_by_source:
        edge_color = edgecolor_by_source(G, node_color)

    if with_labels and label_field:
        node_labels = set_node_label(G, label_field=label_field)
        subset_label_nodes = sorted(zip(G.nodes(), node_size),
                                    key=lambda x: x[1],
                                    reverse=True)[0:num_labels]
        subset_labels = {n[0]: node_labels[n[0]] for n in subset_label_nodes}

    if with_labels and label_field is None:
        subset_labels = dict((n, n) for n in G.nodes())

    # plot the visualization

    fig = plt.figure(figsize=figsize, dpi=fig_dpi, **kwargs)
    ax = fig.add_subplot(111)

    # Draw the nodes, edges, labels separately

    draw_networkx_nodes_custom(G,
                               pos=pos,
                               node_size=node_size,
                               node_color=node_color,
                               ax=ax,
                               alpha=node_opacity,
                               **kwargs)
    plt.axis("scaled")
    nx.draw_networkx_edges(G,
                           pos=pos,
                           edge_color=edge_color,
                           alpha=edge_opacity,
                           **kwargs)

    if with_labels:
        labels = nx.draw_networkx_labels(G,
                                         pos=pos,
                                         labels=subset_labels,
                                         font_size=font_size,
                                         font_color=font_color,
                                         font_family=font_family,
                                         **kwargs)
        if adjust_labels:
            # Adjust label overlapping
            x_pos = [v[0] for k, v in pos.items()]
            y_pos = [v[1] for k, v in pos.items()]
            adjust_text(texts=list(labels.values()), x=x_pos, y=y_pos)

    # add title
    if title:
        plt.title(title)

    ax.axis("off")
    # save the plot

    plt.savefig(filename)

    # Show the plot
    plt.show()
Пример #6
0
import ndlib.models.ModelConfig as mc
import ndlib.models.epidemics as ep

#g = nx.les_miserables_graph()
g = nx.karate_club_graph()

# Prepare node positions for output
positions = force_atlas2_layout(g,
                                iterations=1000,
                                pos_list=None,
                                node_masses=None,
                                outbound_attraction_distribution=False,
                                lin_log_mode=False,
                                prevent_overlapping=False,
                                edge_weight_influence=1.0,

                                jitter_tolerance=1.0,
                                barnes_hut_optimize=True,
                                barnes_hut_theta=0.5,

                                scaling_ratio=2.0,
                                strong_gravity_mode=False,
                                multithread=False,
                                gravity=1.0)

# Model selection
model = ep.SIRModel(g)

# Model Configuration
cfg = mc.Configuration()
cfg.add_model_parameter('beta', 0.5)