Files
CSC111/assignments/A3/a3_visualization.py
T
2022-03-12 18:11:54 -05:00

176 lines
6.2 KiB
Python

"""CSC111 Winter 2022 Assignment 3: Graphs, Recommender Systems, and Clustering (Visualization)
Module Description
==================
This module contains some Python functions that you can use to visualize the graphs
you're working with on this assignment. You should not modify anything in this file.
It will not be submitted for grading.
Disclaimer: we didn't have time to make this file fully PythonTA-compliant!
Copyright and Usage Information
===============================
This file is provided solely for the personal and private use of students
taking CSC111 at the University of Toronto St. George campus. All forms of
distribution of this code, whether as given or with any changes, are
expressly prohibited. For more information on copyright for CSC111 materials,
please consult our Course Syllabus.
This file is Copyright (c) 2022 Mario Badr, David Liu, and Isaac Waller.
"""
import networkx as nx
from plotly.graph_objs import Scatter, Figure
import a3_part1
# Colours to use when visualizing different clusters.
COLOUR_SCHEME = [
'#2E91E5', '#E15F99', '#1CA71C', '#FB0D0D', '#DA16FF', '#222A2A', '#B68100',
'#750D86', '#EB663B', '#511CFB', '#00A08B', '#FB00D1', '#FC0080', '#B2828D',
'#6C7C32', '#778AAE', '#862A16', '#A777F1', '#620042', '#1616A7', '#DA60CA',
'#6C4516', '#0D2A63', '#AF0038'
]
LINE_COLOUR = 'rgb(210,210,210)'
VERTEX_BORDER_COLOUR = 'rgb(50, 50, 50)'
BOOK_COLOUR = 'rgb(89, 205, 105)'
USER_COLOUR = 'rgb(105, 89, 205)'
def visualize_graph(graph: a3_part1.Graph,
layout: str = 'spring_layout',
max_vertices: int = 5000,
output_file: str = '') -> None:
"""Use plotly and networkx to visualize the given graph.
Optional arguments:
- layout: which graph layout algorithm to use
- max_vertices: the maximum number of vertices that can appear in the graph
- output_file: a filename to save the plotly image to (rather than displaying
in your web browser)
"""
graph_nx = graph.to_networkx(max_vertices)
pos = getattr(nx, layout)(graph_nx)
x_values = [pos[k][0] for k in graph_nx.nodes]
y_values = [pos[k][1] for k in graph_nx.nodes]
labels = list(graph_nx.nodes)
kinds = [graph_nx.nodes[k]['kind'] for k in graph_nx.nodes]
colours = [BOOK_COLOUR if kind == 'book' else USER_COLOUR for kind in kinds]
x_edges = []
y_edges = []
for edge in graph_nx.edges:
x_edges += [pos[edge[0]][0], pos[edge[1]][0], None]
y_edges += [pos[edge[0]][1], pos[edge[1]][1], None]
trace3 = Scatter(x=x_edges,
y=y_edges,
mode='lines',
name='edges',
line=dict(color=LINE_COLOUR, width=1),
hoverinfo='none',
)
trace4 = Scatter(x=x_values,
y=y_values,
mode='markers',
name='nodes',
marker=dict(symbol='circle-dot',
size=5,
color=colours,
line=dict(color=VERTEX_BORDER_COLOUR, width=0.5)
),
text=labels,
hovertemplate='%{text}',
hoverlabel={'namelength': 0}
)
data1 = [trace3, trace4]
fig = Figure(data=data1)
fig.update_layout({'showlegend': False})
fig.update_xaxes(showgrid=False, zeroline=False, visible=False)
fig.update_yaxes(showgrid=False, zeroline=False, visible=False)
if output_file == '':
fig.show()
else:
fig.write_image(output_file)
def visualize_graph_clusters(graph: a3_part1.Graph, clusters: list[set],
layout: str = 'spring_layout',
max_vertices: int = 5000,
output_file: str = '') -> None:
"""Visualize the given graph, using different colours to illustrate the different clusters.
Hides all edges that go from one cluster to another. (This helps the graph layout algorithm
positions vertices in the same cluster close together.)
Same optional arguments as visualize_graph (see that function for details).
"""
graph_nx = graph.to_networkx(max_vertices)
all_edges = list(graph_nx.edges)
for edge in all_edges:
# Check if edge is within the same cluster
if any((edge[0] in cluster) != (edge[1] in cluster) for cluster in clusters):
graph_nx.remove_edge(edge[0], edge[1])
pos = getattr(nx, layout)(graph_nx)
x_values = [pos[k][0] for k in graph_nx.nodes]
y_values = [pos[k][1] for k in graph_nx.nodes]
labels = list(graph_nx.nodes)
colors = []
for k in graph_nx.nodes:
for i, c in enumerate(clusters):
if k in c:
colors.append(COLOUR_SCHEME[i % len(COLOUR_SCHEME)])
break
else:
colors.append(BOOK_COLOUR)
x_edges = []
y_edges = []
for edge in graph_nx.edges:
x_edges += [pos[edge[0]][0], pos[edge[1]][0], None]
y_edges += [pos[edge[0]][1], pos[edge[1]][1], None]
trace3 = Scatter(x=x_edges,
y=y_edges,
mode='lines',
name='edges',
line=dict(color=LINE_COLOUR, width=1),
hoverinfo='none'
)
trace4 = Scatter(x=x_values,
y=y_values,
mode='markers',
name='nodes',
marker=dict(symbol='circle-dot',
size=5,
color=colors,
line=dict(color=VERTEX_BORDER_COLOUR, width=0.5)
),
text=labels,
hovertemplate='%{text}',
hoverlabel={'namelength': 0}
)
data1 = [trace3, trace4]
fig = Figure(data=data1)
fig.update_layout({'showlegend': False})
fig.update_xaxes(showgrid=False, zeroline=False, visible=False)
fig.update_yaxes(showgrid=False, zeroline=False, visible=False)
fig.show()
if output_file == '':
fig.show()
else:
fig.write_image(output_file)