Skip to content

Commit

Permalink
added more parameters for hypergraph function
Browse files Browse the repository at this point in the history
and added fix for negative vertices
  • Loading branch information
nnnzs committed May 6, 2024
1 parent ece3072 commit ea1bac2
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 40 deletions.
42 changes: 16 additions & 26 deletions viziphant/patterns.py
Original file line number Diff line number Diff line change
Expand Up @@ -399,8 +399,8 @@ def plot_patterns(spiketrains, patterns, circle_sizes=(3, 50, 70),
axes.yaxis.set_label_coords(-0.01, 0.5)
return axes

def plot_patterns_hypergraph(patterns, node_size=3, pattern_size=None, num_neurons=None,\
highlight_patterns=None, mark_neuron=None, node_color='white'):
def plot_patterns_hypergraph(patterns, pattern_size=None, num_neurons=None,\
must_involve_neuron=None, node_size=3, node_color='white', node_linewidth=1):
"""
Hypergraph visualization of spike patterns.
Expand Down Expand Up @@ -432,17 +432,21 @@ def plot_patterns_hypergraph(patterns, node_size=3, pattern_size=None, num_neuro
pattern detectors.
node_size (optional): int
Change the size of the drawen nodes
pattern_size (optional): tuple or int
pattern_size (optional): range
Only draw patterns that are in range of pattern_size
num_neurons: None or int
If None, only the neurons that are part of a pattern are shown. If an
integer is passed, it identifies the total number of recorded neurons
including non-pattern neurons to be additionally shown in the graph.
Default: None
highlight_patterns (optional) : int
must_involve_neuron (optional) : int
Highlight pattern which includes neuron x
node_color (optional) : String
change the color of the nodes
node_linewidth (optional) : int
change the line width of the nodes
Returns
-------
A handle to a matplotlib figure containing the hypergraph.
Expand Down Expand Up @@ -500,33 +504,18 @@ def plot_patterns_hypergraph(patterns, node_size=3, pattern_size=None, num_neuro

# Create one hypergraph per dataset
hyperedges = []

# Create "range" of pattern_size
if (isinstance(pattern_size, int)): pattern_size=(pattern_size, pattern_size)

# Create one hyperedge from every pattern
for pattern in patterns:
# A hyperedge is the set of neurons of a pattern
if pattern_size is None:
hyperedges.append(pattern['neurons'])
# check if hyperedge(pattern) is greater or equal to min_pattern_size
elif len(pattern['neurons']) >= pattern_size[0] and len(pattern['neurons']) <= pattern_size[1] or highlight_patterns in pattern['neurons']:
if pattern_size is None or len(pattern['neurons']) in pattern_size:
hyperedges.append(pattern['neurons'])

# check if neuron to highlight is in hyperedge
temp_hyperedges = []
if highlight_patterns is not None:
if isinstance(highlight_patterns, int):
for edge in hyperedges:
if highlight_patterns in edge:
temp_hyperedges.append(edge)
hyperedges = temp_hyperedges

# TODO: highlight_patterns as a list

if (len(hyperedges) == 0):
raise Exception('Could not find any hyperedges that match the given parameters')
if must_involve_neuron is not None and isinstance(must_involve_neuron, int):
hyperedges = [edge for edge in hyperedges if must_involve_neuron in edge]

elif must_involve_neuron is not None and isinstance(must_involve_neuron, list):
hyperedges = [edge for edge in hyperedges if any(elem in edge for elem in must_involve_neuron)]

# Currently, all hyperedges receive the same weights
weights = [weight] * len(hyperedges)

Expand All @@ -536,7 +525,8 @@ def plot_patterns_hypergraph(patterns, node_size=3, pattern_size=None, num_neuro
weights=weights,
repulse=repulsive)
hypergraphs.append(hg)
view = View(hypergraphs, node_size, mark_neuron, node_color)
view = View(hypergraphs=hypergraphs, node_size=node_size,
node_color=node_color, node_linewidth=node_linewidth)
fig = view.show(subset_style=VisualizationStyle.COLOR,
triangulation_style=VisualizationStyle.INVISIBLE)

Expand Down
16 changes: 12 additions & 4 deletions viziphant/patterns_src/hypergraph.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,15 +104,23 @@ def complete_and_star_associated_graph(self):
edges = []
weights = []
graph_vertices = list(self.vertices.copy())
if isinstance(self.vertices[0], int):
max_vertex = max(max(hyperedge) for hyperedge in self.hyperedges)
else:
max_vertex = 0
if isinstance(max_vertex, str):
max_vertex = 0
for i, hyperedge in enumerate(self.hyperedges):
# Pseudo-vertex corresponding to hyperedge
graph_vertices.append(-i - 1)
pseudo_vertex = max_vertex + i + 1
graph_vertices.append(pseudo_vertex)

for j, vertex in enumerate(hyperedge):
# Every vertex of a hyperedge is adjacent to the pseudo-vertex
# corresponding to the hyperedge
edges.append([-i - 1, vertex])
# Weight is equal to the weight of the hyperedge (if
# applicable)
edges.append([pseudo_vertex, vertex])

# Weight is equal to the weight of the hyperedge (if applicable)
if self.weights:
weights.append(self.weights[i])
# Unique unordered combinations of vertices of this hyperedge
Expand Down
19 changes: 9 additions & 10 deletions viziphant/patterns_src/view.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,7 @@ class View:
In summary, this class represents an interactive tool
for the visualization of hypergraphs.
"""

def __init__(self, hypergraphs, node_size=3, mark_neuron=None, node_color='white', title=None):
def __init__(self, hypergraphs, node_size=3, node_color='white', node_linewidth=1, title=None):
"""
Constructs a View object that handles the visualization
of the given hypergraphs.
Expand All @@ -49,11 +48,11 @@ def __init__(self, hypergraphs, node_size=3, mark_neuron=None, node_color='white
node_size (optional) : int
Size of the nodes in the Hypergraphs
mark_neuron (optional) : int
Neuron with given number will be highlighted
node_color (optional) : String
change the color of the nodes
node_linewidth (optional) : int
change the line width of the nodes
"""

# Hyperedge drawings
Expand All @@ -71,12 +70,12 @@ def __init__(self, hypergraphs, node_size=3, mark_neuron=None, node_color='white
# Color of the nodes
self.node_color = node_color

# Width of the Node lines
self.node_linewidth = node_linewidth

# Selected title of the figure
self.title = title

# Marked node will be in a different color
self.mark_neuron = mark_neuron

# If no data was provided, fill in dummy data
if hypergraphs:
self.hypergraphs = hypergraphs
Expand Down Expand Up @@ -125,7 +124,7 @@ def _setup_graph_visualization(self):
# The hv.Graph visualization is used for displaying the data
# hv.Graph displays the nodes (and optionally binary edges) of a graph
dynamic_map = hv.DynamicMap(hv.Graph, streams=[pipe])

# Define options for visualization
dynamic_map.opts(
# Some space around the Graph in order to avoid nodes being on the
Expand All @@ -142,7 +141,7 @@ def _setup_graph_visualization(self):
# All in black
cmap=['#ffffff', '#ffffff'] * 50,
# Size of the nodes
node_size=self.node_size, node_color=self.node_color, show_legend=True))
node_size=self.node_size, node_color=self.node_color, node_linewidth=self.node_linewidth, show_legend=True))
return dynamic_map, pipe

def _setup_hyperedge_drawing(self):
Expand Down

0 comments on commit ea1bac2

Please sign in to comment.