hari_plotter.graph module

class hari_plotter.graph.Graph(incoming_graph_data=None, **attr)[source]

Bases: DiGraph

HariGraph extends the NetworkX DiGraph class to provide additional functionalities specific to complex network analysis and manipulation. It includes methods for graph parameterization, node merging, influence assignment, and serialization/deserialization to/from JSON format.

gatherer

An instance of a NodeEdgeGatherer subclass responsible for collecting and applying node and edge parameters based on defined criteria.

Type:

NodeEdgeGatherer

add_parameters_to_nodes(nodes: list[tuple[int]] | None = None) None[source]

Adds or updates parameters for the specified nodes based on the current gatherer’s criteria. If no nodes are specified, parameters are added or updated for all nodes in the graph.

Parameters:

nodes (Optional[list[tuple[int]]]) – list of node identifiers to update. If None, updates all nodes.

assign_parameter(parameter: str, method: dict | None = None) None[source]

Assigns random opinions to all nodes in the graph.

Parameters:

parameter (str) – The parameter to be assigned random values.

assign_random_influences(mean_influence: float, influence_range: float, seed: int | None = None) None[source]

Assigns random influence values to all edges within a specified range centered around a mean influence value.

Parameters:
  • mean_influence (float) – The mean value around which the influence values are centered.

  • influence_range (float) – The range within which the random influence values will vary.

  • seed (Optional[int]) – An optional seed for the random number generator for reproducibility (default is None).

classmethod by_deletion(n: int, factor: float) Graph[source]

Creates a HariGraph instance by deleting some of the edges of a fully connected graph.

Parameters:
  • (int) (n) – Number of nodes.

  • (float) (factor) – Factor representing how many edges to keep.

Returns:

A new HariGraph instance.

check_all_paths_exist() bool[source]

Checks if there exists a path between every pair of nodes in the HariGraph instance.

Returns:

True if a path exists between every pair of nodes, False otherwise.

copy() Graph[source]

Returns a copy of the graph.

The copy method by default returns an independent shallow copy of the graph and attributes. That is, if an attribute is a container, that container is shared by the original an the copy. Use Python’s copy.deepcopy for new containers.

If as_view is True then a view is returned instead of a copy.

Notes

All copies reproduce the graph structure, but data attributes may be handled in different ways. There are four types of copies of a graph that people might want.

Deepcopy – A “deepcopy” copies the graph structure as well as all data attributes and any objects they might contain. The entire graph object is new so that changes in the copy do not affect the original object. (see Python’s copy.deepcopy)

Data Reference (Shallow) – For a shallow copy the graph structure is copied but the edge, node and graph attribute dicts are references to those in the original graph. This saves time and memory but could cause confusion if you change an attribute in one graph and it changes the attribute in the other. NetworkX does not provide this level of shallow copy.

Independent Shallow – This copy creates new independent attribute dicts and then does a shallow copy of the attributes. That is, any attributes that are containers are shared between the new graph and the original. This is exactly what dict.copy() provides. You can obtain this style copy using:

>>> G = nx.path_graph(5)
>>> H = G.copy()
>>> H = G.copy(as_view=False)
>>> H = nx.Graph(G)
>>> H = G.__class__(G)

Fresh Data – For fresh data, the graph structure is copied while new empty data attribute dicts are created. The resulting graph is independent of the original and it has no edge, node or graph attributes. Fresh copies are not enabled. Instead use:

>>> H = G.__class__()
>>> H.add_nodes_from(G)
>>> H.add_edges_from(G.edges)

View – Inspired by dict-views, graph-views act like read-only versions of the original graph, providing a copy of the original structure without requiring any memory for copying the information.

See the Python copy module for more information on shallow and deep copies, https://docs.python.org/3/library/copy.html.

Parameters:

as_view (bool, optional (default=False)) – If True, the returned graph-view provides a read-only view of the original graph without actually copying any data.

Returns:

G – A copy of the graph.

Return type:

Graph

See also

to_directed

return a directed copy of the graph.

Examples

>>> G = nx.path_graph(4)  # or DiGraph, MultiGraph, MultiDiGraph, etc
>>> H = G.copy()
dynamics_example_step(t: float)[source]

Updates the opinion of each node in the HariGraph instance based on the opinions of its predecessors.

Parameters:

t – The time step factor influencing the dynamics.

find_clusters(max_opinion_difference: float = 0.1, min_influence: float = 0.1)[source]

Finds clusters of nodes in the graph where the difference in the nodes’ opinions is less than max_opinion_difference, and the influence of i on j is higher than min_influence * size(i).

Parameters:
  • max_opinion_difference (float) – Maximum allowed difference in the opinions of nodes to form a cluster.

  • min_influence (float) – Minimum required influence to form a cluster, adjusted by the size of the node.

Returns:

A list of lists, where each inner list represents a cluster of node identifiers.

Return type:

list[list[int]]

get_cluster_mapping() list[list[tuple[int]]][source]

Generates a list of nodes in the unclustered graph to be clustered to get the current graph :return: A list representing the current clusters in the graph.

get_graph() Graph[source]

Self call for union formatting with LazyHariGraph

classmethod guaranteed_connected(n: int) Graph[source]

Creates a guaranteed connected HariGraph instance with n nodes.

Parameters:

(int) (n) – Number of nodes.

Returns:

A new HariGraph instance.

has_self_loops() bool[source]

Checks if the graph contains any self-loops (edges that connect a node to itself).

Returns:

True if there is at least one self-loop in the graph, otherwise False.

Return type:

bool

is_degroot_converging(tolerance: float = 0.01) bool[source]

Checks if the graph’s influence structure adheres to the Degroot convergence criteria, i.e., the total incoming influence for each node is within a tolerance of 1.

Parameters:

tolerance (float) – The tolerance within which the total influence must fall to be considered converging.

Returns:

True if the graph meets the Degroot convergence criteria, otherwise False.

Return type:

bool

make_degroot_converging(seed: int | None = None) None[source]

Adjusts the influence values on incoming edges for each node to ensure the graph meets the Degroot convergence criteria, i.e., the total incoming influence for each node equals 1.

Parameters:

seed (Optional[int]) – An optional seed for the random number generator for reproducibility (default is None).

mean_graph(images: list[Graph]) Graph[source]

Calculates the mean graph from a list of HariGraph instances. The mean graph’s nodes and edges have attributes that are the average of the corresponding attributes in the input graphs.

Parameters:

images (list['HariGraph']) – A list of HariGraph instances from which to calculate the mean graph.

Returns:

A new HariGraph instance representing the mean of the input graphs.

Return type:

‘HariGraph’

property mean_opinion: float

Calculates the weighted mean opinion of the nodes in the graph.

For each node, its opinion is multiplied by its weight. The weight of a node is the length of its label if defined, otherwise, it is assumed to be 1. The method returns the sum of the weighted opinions divided by the sum of the weights.

Returns:

The weighted mean opinion of the nodes in the graph.

Returns 0 if the total weight is 0 to avoid division by zero.

Return type:

float

merge_by_intervals(intervals: list[float])[source]

Merges nodes into clusters based on the intervals defined by the input list of opinions.

Parameters:

intervals (list[float]) – A sorted list of opinions representing the boundaries of the intervals.

merge_clusters(clusters: list[list[tuple[int]]], labels: list[str] | None = None, merge_remaining=False)[source]

Merges clusters of nodes in the graph into new nodes. Optionally merges the remaining nodes into an additional cluster.

Parameters:
  • clusters (Union[list[Set[int]], dict[int, int]]) – A list where each element is a set containing the IDs of the nodes in a cluster to be merged or a dictionary mapping old node IDs to new node IDs.

  • merge_remaining (bool) – If True, merge the nodes not included in clusters into an additional cluster. Default is False.

merge_nodes(i: tuple[int], j: tuple[int])[source]

Merges two nodes in the graph into a new node.

The new node’s opinion is a weighted average of the opinions of the merged nodes, and its name is the concatenation of the names of the merged nodes. The edges are reconnected to the new node, and the old nodes are removed.

Parameters:
  • tuple[int] (j) – The identifier for the first node to merge.

  • tuple[int] – The identifier for the second node to merge.

property node_parameters
property opinions

Returns a dictionary with the opinions of the nodes. Key is the node ID, and opinion is the opinion of the node.

position_nodes(seed=None)[source]

Determines the positions of the nodes in the graph using the spring layout algorithm.

Parameters:

seed – int, optional Seed for the spring layout algorithm, affecting the randomness in the positioning of the nodes. If None, the positioning of the nodes will be determined by the underlying algorithm’s default behavior. Default is None.

Returns:

dict A dictionary representing the positions of the nodes in a 2D space, where the keys are node IDs and the opinions are the corresponding (x, y) coordinates.

classmethod read_json(filename: str, gatherer: NodeEdgeGatherer | None = None) Graph[source]

Reads a HariGraph instance from a JSON file that contains both the graph’s structure and node attributes.

Parameters:
  • filename (str) – Path to the JSON file from which the graph is to be loaded.

  • gatherer (NodeEdgeGatherer | None) – type of gatherer to be used

Returns:

A new HariGraph instance constructed based on the data contained in the JSON file. This method reconstructs the graph’s nodes, edges, and associated attributes like opinions and influences.

Return type:

HariGraph

classmethod read_network(network_file: str, opinion_file: str, gatherer: NodeEdgeGatherer | None = None, number_of_bots: int = 0) Graph[source]

Reads a graph structure and node attributes from separate files and initializes a HariGraph instance with this data.

Parameters:
  • network_file (str) – Path to the file containing the network’s topology, specifying nodes and their connections.

  • opinion_file (str) – Path to the file containing node attributes, specifically their opinions and optionally activities.

  • gatherer (NodeEdgeGatherer | None) – type of gatherer to be used

  • number_of_bots (int) – number of bots. First number_of_bots lines will be interpreted as bots

Returns:

An instance of HariGraph populated with nodes, edges, and node attributes based on the provided files.

Return type:

HariGraph

remove_self_loops() None[source]

Removes all self-loops from the graph.

set_gatherer(new_gatherer: Type[NodeEdgeGatherer]) None[source]

Sets a new gatherer for collecting and applying node and edge parameters.

Parameters:

new_gatherer (Type[NodeEdgeGatherer]) – The new gatherer class to be used.

classmethod strongly_connected_components(cluster_sizes: list[int], inter_cluster_edges: int, mean_opinion: float = 0.5, seed: int | None = None) Graph[source]

Creates a HariGraph instance with multiple strongly connected components.

Parameters:
  • cluster_sizes – list[int], sizes of the clusters.

  • inter_cluster_edges – int, number of edges between the components.

  • mean_opinion – float, mean opinion of the graph.

  • seed – int, random seed.

Returns:

A new HariGraph instance.

classmethod unconnected(n: int) Graph[source]

Creates a HariGraph instance with n nodes and no edges.

Parameters:

(int) (n) – Number of nodes.

Returns:

A new HariGraph instance.

write_json(filename: str)[source]

Serializes the graph to a JSON file, including its structure (nodes and edges) and attributes (e.g., opinions).

Parameters:

filename (str) – The file path where the graph will be saved in JSON format.

This method creates a JSON representation of the graph, which includes detailed information about nodes and edges along with their attributes, making it suitable for storage, sharing, or further analysis.

write_network(network_file: str, opinion_file: str, delimiter=',')[source]

Writes the current graph’s network structure and node attributes to specified files, using integers to represent node IDs based on a sorted mapping. The output is saved in the sorted order of these integer IDs.

Parameters:
  • network_file (str) – Path to the file where the network structure will be saved.

  • opinion_file (str) – Path to the file where the node attributes, particularly opinions, will be saved.

  • delimiter (str) – The delimiter used to separate values in the output files.