Skip to content

Commit

Permalink
updated
Browse files Browse the repository at this point in the history
  • Loading branch information
roholazandie committed Dec 2, 2024
1 parent 0c1eacc commit 2568ea6
Show file tree
Hide file tree
Showing 12 changed files with 400 additions and 653 deletions.
86 changes: 63 additions & 23 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,37 +1,77 @@
# Graph Drawing using Plotly+Graphviz
This project shows a usecase of using graphviz layout on plotly network plot.
You can read more about this repository [this](https://medium.com/@hilbert.cantor/network-plot-with-plotly-and-graphviz-ebd7778073b) medium post.
# Graph Visualization Tool

This repository provides tools to visualize graphs using Plotly. It supports both 2D and 3D visualizations with customizable layouts, node sizes, edge weights, and edge colors.

# Installation
First of all you need to install the graphviz package(for ubuntu):
## Features

`> sudo apt-get install graphviz libgraphviz-dev pkg-config`
- Visualize graphs in 2D or 3D.
- Support for various layout algorithms (`graphviz`, `spring`, `spectral`, `random`).
- Customize node sizes, edge weights, and edge colors.
- Generate output as interactive HTML files.

And then install the requirements.txt file:
## Installation

`> pip install -r requirements.txt`
1. Install Graphviz (for Ubuntu):

the only requirements are plotly and networkx and pygraphviz.
```bash
sudo apt-get install graphviz libgraphviz-dev pkg-config
```

# Motivation
The motivation of writing this script is to provide a more easier and appealing network plots
using beautiful plotly plots and graphviz layout.
2. Install Python dependencies:

# Usage
After installation of requirements then you can take a look at the main script. There are couple of ways to call the visualize_graph method.
In the simplest format you just need to pass the graph (in networkx format).
```bash
pip install -r requirements.txt
```

`visualize_graph(G)`
## Usage

in full format you can specify node labels, node sizes, edge weights, layout, file_name and title of the
plot. Here is one call:
### Running the Main Script

`visualize_graph(G, node_labels, node_sizes, edge_weights, layout, filename="outputs/test.html", title="My title")`
To visualize a graph, run the main script with the following command-line arguments:

You should be careful about the order of the parameters list. Just use networkx call to edges and nodes lists.
```bash
python main.py --layout <layout> --node_size <size> --output <output_file> --title <title>
```

You can also use the 3d version of the graph visualization which is based on spring layout.
for 3d usage you can do like this:
### Command-line Options

`visualize_graph_3d(graph, node_labels, node_sizes, filename="outputs/test.html")`
- `--layout`: Specifies the layout algorithm for positioning the graph. Options: `graphviz`, `spring`, `spectral`, `random`. Default: `graphviz`.
- `--node_size`: Sets the size of the nodes. Default: `20`.
- `--output`: Specifies the output file name for the HTML visualization. Default: `outputs/graphviz.html`.
- `--title`: Sets the title for the visualization. Default: `Graph Visualization`.

### Example

#### 2D Graph Visualization

```bash
python main.py --layout graphviz --node_size 20 --output outputs/graphviz.html --title "2D Graph Visualization"
```

#### 3D Graph Visualization

```bash
python main.py --layout spring --node_size 30 --output outputs/spring_3d.html --title "Spring Layout 3D Visualization"
```

### Additional Layouts

You can add new layout options by extending the `--layout` argument in the script and implementing the corresponding layout logic.

## Repository Structure

- `main.py`: The main script for visualizing graphs.
- `plotly_visualize.py`: Helper functions for 2D and 3D visualizations.
- `outputs/`: Directory for storing the generated HTML files.

## Contributing

Contributions are welcome! Feel free to open issues or create pull requests to improve this repository.

## License

This project is licensed under the MIT License.

## Additional Resources

For more details on using Plotly with Graphviz, check out [this Medium post](https://medium.com/@hilbert.cantor/network-plot-with-plotly-and-graphviz-ebd7778073b).
Binary file removed graph.gpickle
Binary file not shown.
73 changes: 44 additions & 29 deletions main.py
Original file line number Diff line number Diff line change
@@ -1,34 +1,49 @@
'''
In this script we try to compare the result of graph drawing
with different layouts with plotly visualization library
Here we use a predefined graph saved as pickle format
you can use any other graph as input to the function
'''

import argparse
import numpy as np
import networkx as nx
from plotly_visualize import visualize_graph

def get_edge_weights(G):
weights = [G[u][v]['weight'] for u, v in G.edges()]
return weights


def get_node_sizes(G):
node_sizes = nx.get_node_attributes(G, 'importance').values()
return node_sizes


def get_node_labels(G):
return G.nodes()
import matplotlib.colors as mcolors
import matplotlib.pyplot as plt


def main():
parser = argparse.ArgumentParser(description="Visualize a graph with different layouts using Plotly.")
parser.add_argument("--layout", type=str, default="graphviz",
choices=["graphviz", "spring", "spectral", "random"],
help="Layout algorithm for graph positioning.")
parser.add_argument("--node_size", type=int, default=20,
help="Size of the nodes.")
parser.add_argument("--output", type=str, default="outputs/graphviz.html",
help="Output filename for the visualization.")
parser.add_argument("--title", type=str, default="Graph Visualization",
help="Title for the visualization.")

args = parser.parse_args()

# Generate a scale-free graph
graph = nx.scale_free_graph(100)

# Generate random edge weights
edge_weights = np.random.randint(1, 5, len(graph.edges())).tolist()

# Generate edge colors
edge_colors = {}
norm = mcolors.Normalize(vmin=-5, vmax=5)
cmap = plt.get_cmap('coolwarm')
for u, v in graph.edges():
edge_colors[(u, v)] = mcolors.rgb2hex(cmap(norm(np.random.randint(-5, 5))))

# Visualize the graph
visualize_graph(
G=graph,
layout=args.layout,
edge_weights=edge_weights,
edge_colors=edge_colors,
node_sizes=args.node_size,
filename=args.output,
title=args.title
)


if __name__ == "__main__":
graph = nx.read_gpickle("graph.gpickle")
node_sizes = get_node_sizes(graph)
edge_weights = get_edge_weights(graph)
node_labels = get_node_labels(graph)
layout = "spectral"
visualize_graph(graph, node_labels, node_sizes, edge_weights, layout, filename="outputs/"+layout+".html", title=layout)
#visualize_graph(graph, node_labels, node_sizes, layout, filename="outputs/"+layout+".html", title="")


main()
69 changes: 45 additions & 24 deletions main3d.py
Original file line number Diff line number Diff line change
@@ -1,25 +1,46 @@
from plotly_visualize import visualize_graph_3d
import argparse
import numpy as np
import networkx as nx

def get_edge_weights(G):
weights = [G[u][v]['weight'] for u, v in G.edges()]
return weights


def get_node_sizes(G):
node_sizes = nx.get_node_attributes(G, 'importance').values()
return node_sizes


def get_node_labels(G):
return G.nodes()



graph = nx.read_gpickle("graph.gpickle")
node_sizes = get_node_sizes(graph)
edge_weights = get_edge_weights(graph)
node_labels = get_node_labels(graph)
layout = "graphviz"
filename= "outputs/"+layout+"3d.html"
visualize_graph_3d(graph, node_labels, node_sizes, filename=filename, title="3D visualization")
from plotly_visualize import visualize_graph_3d
import matplotlib.colors as mcolors
import matplotlib.pyplot as plt

def main():
parser = argparse.ArgumentParser(description="Visualize a 3D graph with customizable layouts and styles.")
parser.add_argument("--layout", type=str, default="graphviz",
choices=["graphviz", "spring", "spectral", "random"],
help="Layout algorithm for graph positioning.")
parser.add_argument("--node_size", type=int, default=20,
help="Size of the nodes.")
parser.add_argument("--output", type=str, default="outputs/graphviz_3d",
help="Output filename for the 3D visualization.")
parser.add_argument("--title", type=str, default="3D Graph Visualization",
help="Title for the 3D visualization.")

args = parser.parse_args()

# Generate a scale-free graph
graph = nx.scale_free_graph(100)

# Generate random edge weights
edge_weights = np.random.randint(1, 5, len(graph.edges())).tolist()

# Generate edge colors
edge_colors = {}
norm = mcolors.Normalize(vmin=-5, vmax=5)
cmap = plt.get_cmap('coolwarm')
for u, v in graph.edges():
edge_colors[(u, v)] = mcolors.rgb2hex(cmap(norm(np.random.randint(-5, 5))))

# Visualize the graph in 3D
visualize_graph_3d(
G=graph,
node_sizes=args.node_size,
edge_colors=edge_colors,
edge_weights=edge_weights,
filename=args.output,
title=args.title
)

if __name__ == "__main__":
main()
89 changes: 11 additions & 78 deletions outputs/graphviz.html

Large diffs are not rendered by default.

81 changes: 0 additions & 81 deletions outputs/graphviz3d.html

This file was deleted.

14 changes: 14 additions & 0 deletions outputs/graphviz_3d.html

Large diffs are not rendered by default.

81 changes: 0 additions & 81 deletions outputs/random.html

This file was deleted.

81 changes: 0 additions & 81 deletions outputs/spectral.html

This file was deleted.

81 changes: 0 additions & 81 deletions outputs/spring.html

This file was deleted.

Loading

0 comments on commit 2568ea6

Please sign in to comment.