Skip to content

Commit

Permalink
Merge 99190b8 into 362a0ac
Browse files Browse the repository at this point in the history
  • Loading branch information
MengLiuPurdue committed Dec 6, 2018
2 parents 362a0ac + 99190b8 commit 03ce49d
Show file tree
Hide file tree
Showing 4 changed files with 222 additions and 37 deletions.
9 changes: 3 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ The current version is 0.4.4 and it is appropriate for experts and intermediates
- Global spectral partitioning
- Densest subgraph
- [Triangle clusters and vertex neighborhood metrics](https://arxiv.org/pdf/1112.0031.pdf)
- Handy network drawing methods

## Pipelines

Expand Down Expand Up @@ -80,18 +81,14 @@ print("Conductance after improvement:",g.compute_conductance(output_SL_fast[0]))
output_SL = output_SL_fast[0]
```

## Examples with visualization for social networks
## Examples with visualization

For examples with visualization of the output see the Jupyter notebooks [examples with visualization](https://github.com/kfoynt/LocalGraphClustering/blob/master/notebooks/examples_with_visualization.ipynb), [more examples with visualization](https://github.com/kfoynt/LocalGraphClustering/blob/master/notebooks/more_examples_with_visualization.ipynb).
For general examples with visualization using our built-in drawing methods, see the Jupyter notebook [examples with visualization](https://github.com/kfoynt/LocalGraphClustering/blob/master/notebooks/new_visualization_examples.ipynb).

For comparisons of spectral- and flow-based methods with visualization see the Jupyter notebooks [here](https://github.com/kfoynt/LocalGraphClustering/blob/master/notebooks/spectral_vs_flow_with_visualization.ipynb) and [here](https://github.com/kfoynt/LocalGraphClustering/blob/master/notebooks/spectral_vs_flow_2_with_visualization.ipynb).

For visual demonstration of algorithms that can improve a given seed set of nodes see the Jupyter notebook [here](https://github.com/kfoynt/LocalGraphClustering/blob/master/notebooks/improveType_algorithms_with_visualization.ipynb).

## Examples with visualization for bioinformatics networks

For examples with visualization see the Jupyter notebook [bioinformatics examples with visualization](https://github.com/kfoynt/LocalGraphClustering/blob/master/notebooks/examples_Bioinformatics_with_visualization.ipynb).

## Scalable graph analytics on your laptop

For examples using reasonably large graphs (100 million edges) on a 16GB RAM laptop please see the Jupyter notebook [here](https://github.com/kfoynt/LocalGraphClustering/blob/master/notebooks/examples_scalable_graph_analytics.ipynb).
Expand Down
150 changes: 147 additions & 3 deletions localgraphclustering/GraphDrawing.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,33 @@
from matplotlib.cm import ScalarMappable

class GraphDrawing:
"""
This class implements all the drawing related methods for a GraphLocal
instance. These methods include changing colors, highlighting a set etc.
It is not designed to be used individually. Its purpose is to change all
kinds of drawing properties after calling standard drawing functions,
"draw" and "draw_groups" in GraphLocal.
Attributes
----------
G : GraphLocal instance
coords : a n-by-2 or n-by-3 array with coordinates for each node of the graph.
ax,fig : None,None (default)
by default it will create a new figure, or this will plot in axs if not None.
is_3d : True when it is a 3D graph
nodes_collection : a matplotlib PathCollection instance containing all nodes
edge_collection : a matplotlib LineCollection instance containing all edges
groups : list[list] or list, for the first case, each sublist represents a cluster
for the second case, list must have the same length as the number of nodes and
nodes with the number are in the same cluster
"""
def __init__(self,G,coords,ax=None,groups=None,figsize=None):
self.G = G
self.coords = coords
Expand Down Expand Up @@ -45,11 +72,37 @@ def _plotting_build_edgepos(G,pos):
GraphDrawing._plotting_push_edges_for_node(i,G.aj[G.ai[i]:G.ai[i+1]],pos,edge_pos,edge_mapping)
edge_pos = np.asarray(edge_pos)
return edge_pos,edge_mapping

def show(self):
"""
show the graph
"""
return self.fig

def highlight(self,nodelist,othernodes=False,otheredges=False,filled=False,alpha=0):
"""
highlight a set of nodes
Parameters
----------
nodelist: a list of nodes to be highlighted
Optional parameters
------------------
othernodes: bool (False by default)
whether to hide nodes that is not in the nodelist
otheredges: bool (False by default)
whether to hide edges that doesn't connect two nodes in the nodelist
filled: bool (False by default)
set to True to only circle nodes in the nodelist
alpha: float (1.0 by default)
change alpha for nodes in the nodelist
"""
nodeset = set(nodelist)
if not othernodes or not filled:
node_out = list(set(range(self.G._num_vertices)) - nodeset)
Expand All @@ -63,10 +116,16 @@ def highlight(self,nodelist,othernodes=False,otheredges=False,filled=False,alpha
self.edgecolor(i,j,alpha=alpha)

def only_circle_nodes(self,nodeset):
"""
only circle the nodes in nodeset
"""
facecolors = self.nodes_collection.get_facecolor()
facecolors[nodeset] = [0,0,0,0]

def between_group_alpha(self,alpha):
"""
change the edge alpha value for edges that connect nodes from different groups
"""
if self.groups is not None:
if self.groups.ndim == 2:
node_mapping = np.zeros(self.G._num_vertices,dtype=self.G.aj.dtype)
Expand All @@ -80,6 +139,27 @@ def between_group_alpha(self,alpha):


def nodecolor(self,node,c=None,edgecolor=None,facecolor=None,alpha=None):
"""
change node color
Parameters
----------
node: integer or list[integer]
c: string or rgb or rgba (None by default)
when set to be None, this function just returns the current colors for the node
edgecolor,facecolor: (None by default)
used when you want different edgecolor and facecolor for the node
when set to be None, it will be same as "c"
alpha: float (None by default)
when set to be None, alpha will not be changed
Returns
-------
current node color
"""
if c is not None:
edgecolor = c
facecolor = c
Expand All @@ -91,13 +171,51 @@ def nodecolor(self,node,c=None,edgecolor=None,facecolor=None,alpha=None):
self._plotting_update_color(colors,node,edgecolor,alpha)

return self.nodes_collection.get_facecolor()[node]


# The better way here might be diectly modifying self.edge_collection._paths
def edgecolor(self,i,j,c=None,alpha=None):
"""
change edge color
Parameters
----------
i,j: integer, start and end node of the edge
c: string or rgb or rgba (None by default)
when set to be None, this function just returns the current colors for the edge
alpha: float (None by default)
when set to be None, alpha will not be changed
Returns
-------
current edge color
"""
colors = self.edge_collection.get_edgecolor()
if len(colors) == 1:
colors = np.array([colors[0]]*self.G._num_edges)
self.edge_collection.set_edgecolor(c=colors)
idx = self.edge_mapping[(i,j)]
return self._plotting_update_color(colors,idx,c,alpha)

def nodesize(self,node,nodesize):
"""
change node size
Parameters
----------
node: integer or list[integer]
nodesize: float, int, list[int] or list[float]
in the latter two cases, the length of nodesize must
be the same as the length of node
Returns
-------
current node size
"""
sizes = self.nodes_collection.get_sizes()
if len(sizes) == 1:
sizes = np.array([sizes[0]]*self.G._num_vertices)
Expand All @@ -109,6 +227,18 @@ def nodesize(self,node,nodesize):
return sizes[node]

def nodewidth(self,node,width):
"""
change line width of node
Parameters
----------
node: integer or list[integer]
width: float, int, list[int] or list[float]
in the latter two cases, the length of nodesize must
be the same as the length of node
"""
widths = np.asarray(self.nodes_collection.get_linewidths())
if len(widths) == 1:
widths = np.array([widths[0]]*self.G._num_vertices)
Expand Down Expand Up @@ -137,14 +267,28 @@ def _plotting_update_color(container,key,c,alpha):
return container[key]

def scatter(self,**kwargs):
"""
a wrapper of standard matplotlib scatter function
Parameters
----------
**kwargs: same as the parameters in matplotlib scatter
"""
coords = self.coords
if len(self.coords[0]) == 2:
self.nodes_collection = self.ax.scatter([p[0] for p in coords],[p[1] for p in coords],**kwargs)
else:
self.nodes_collection = self.ax.scatter([p[0] for p in coords],[p[1] for p in coords],[p[2] for p in coords],**kwargs)
self.ax._sci(self.nodes_collection)

def plot(self,**kwargs):
"""
a wrapper of standard matplotlib plot function
Parameters
----------
**kwargs: same as the parameters in matplotlib plot
"""
if len(self.coords[0]) == 2:
self.edge_collection = LineCollection(self.edge_pos,**kwargs)
else:
Expand Down
89 changes: 70 additions & 19 deletions localgraphclustering/GraphLocal.py
Original file line number Diff line number Diff line change
Expand Up @@ -644,6 +644,64 @@ def draw(self,coords,alpha=1.0,nodesize=5,linewidth=1,
nodealpha=1.0,edgealpha=1.0,edgecolor='k',nodemarker='o',
axs=None,fig=None,values=None,cm=None,valuecenter=None,angle=30,
figsize=None,nodecolor='r'):


"""
Standard drawing function when having single cluster
Parameters
----------
coords: a n-by-2 or n-by-3 array with coordinates for each node of the graph.
Optional parameters
------------------
alpha: float (1.0 by default)
the overall alpha scaling of the plot, [0,1]
nodealpha: float (1.0 by default)
the overall node alpha scaling of the plot, [0, 1]
edgealpha: float (1.0 by default)
the overall edge alpha scaling of the plot, [0, 1]
nodecolor: string or RGB ('r' by default)
edgecolor: string or RGB ('k' by default)
setcolor: string or RGB ('y' by default)
nodemarker: string ('o' by default)
nodesize: float (5.0 by default)
linewidth: float (1.0 by default)
axs,fig: None,None (default)
by default it will create a new figure, or this will plot in axs if not None.
values: Sequence[float] (None by default)
used to determine node colors in a colormap, should have the same length as coords
valuecenter: often used with values together to determine vmin and vmax of colormap
offset = max(abs(values-valuecenter))
vmax = valuecenter + offset
vmin = valuecenter - offset
cm: string or colormap object (None by default)
figsize: tuple (None by default)
angle: float (30 by default)
set initial view angle when drawing 3d
Returns
-------
A GraphDrawing object
"""

if values is not None:
values = np.asarray(values)
if values.ndim == 2:
Expand Down Expand Up @@ -678,13 +736,17 @@ def draw_groups(self,coords,groups,alpha=1.0,nodesize=5,linewidth=1,
nodealpha=1.0,edgealpha=0.01,edgecolor='k',nodemarker='o',axs=None,
fig=None,cm=None,angle=30,figsize=None):
"""
standard drawing function of GraphLocal object
Standard drawing function when having multiple clusters
Parameters
----------
coords: a n-by-2 or n-by-3 array with coordinates for each node of the graph.
groups: list[list] or list, for the first case, each sublist represents a cluster
for the second case, list must have the same length as the number of nodes and
nodes with the number are in the same cluster
Optional parameters
------------------
Expand All @@ -697,41 +759,30 @@ def draw_groups(self,coords,groups,alpha=1.0,nodesize=5,linewidth=1,
edgealpha: float (1.0 by default)
the overall edge alpha scaling of the plot, [0, 1]
setalpha: float (1.0 by default)
the overall set alpha scaling of the plot, [0, 1]
nodecolor: string or RGB ('r' by default)
edgecolor: string or RGB ('k' by default)
setcolor: string or RGB ('y' by default)
nodemarker: string ('o' by default)
nodesize: float (5.0 by default)
linewidth: float (1.0 by default)
nodeset: Sequence[int] (None by default)
a set of nodes to highlight
groups: Sequence[Sequence[int]] (None by default)
node partitions, different colors will be assigned to different groups
axs,fig: None,None (default)
by default it will create a new figure, or this will plot in axs if not None.
values: Sequence[float] (None by default)
used to determine node colors in a colormap, should have the same length as coords
cm: string or colormap object (None by default)
figsize: tuple (None by default)
cm: string ("Reds" by default)
colormap
angle: float (30 by default)
set initial view angle when drawing 3d
Returns
-------
a dictionary with:
fig, ax, setnodes, groupnodes
A GraphDrawing object
"""

#when values are not provided, use tab20 or gist_ncar colormap to determine colors
Expand Down
Loading

0 comments on commit 03ce49d

Please sign in to comment.