@@ -838,6 +838,198 @@ def lab2node(labels, labels_dict):
838
838
return [labels_dict [ll ] for ll in labels ]
839
839
840
840
841
+ ### Patched version for networx draw_networkx_edges, sent to Aric.
842
+ def draw_networkx_edges (G , pos ,
843
+ edgelist = None ,
844
+ width = 1.0 ,
845
+ edge_color = 'k' ,
846
+ style = 'solid' ,
847
+ alpha = None ,
848
+ edge_cmap = None ,
849
+ edge_vmin = None ,
850
+ edge_vmax = None ,
851
+ ax = None ,
852
+ arrows = True ,
853
+ ** kwds ):
854
+ """Draw the edges of the graph G
855
+
856
+ This draws only the edges of the graph G.
857
+
858
+ pos is a dictionary keyed by vertex with a two-tuple
859
+ of x-y positions as the value.
860
+ See networkx.layout for functions that compute node positions.
861
+
862
+ edgelist is an optional list of the edges in G to be drawn.
863
+ If provided, only the edges in edgelist will be drawn.
864
+
865
+ edgecolor can be a list of matplotlib color letters such as 'k' or
866
+ 'b' that lists the color of each edge; the list must be ordered in
867
+ the same way as the edge list. Alternatively, this list can contain
868
+ numbers and those number are mapped to a color scale using the color
869
+ map edge_cmap. Finally, it can also be a list of (r,g,b) or (r,g,b,a)
870
+ tuples, in which case these will be used directly to color the edges. If
871
+ the latter mode is used, you should not provide a value for alpha, as it
872
+ would be applied globally to all lines.
873
+
874
+ For directed graphs, 'arrows' (actually just thicker stubs) are drawn
875
+ at the head end. Arrows can be turned off with keyword arrows=False.
876
+
877
+ See draw_networkx for the list of other optional parameters.
878
+
879
+ """
880
+ try :
881
+ import matplotlib .pylab as pylab
882
+ import matplotlib .cbook as cb
883
+ from matplotlib .colors import colorConverter , Colormap
884
+ from matplotlib .collections import LineCollection
885
+ except ImportError :
886
+ raise ImportError ("Matplotlib required for draw()" )
887
+ except RuntimeError :
888
+ pass # unable to open display
889
+
890
+ if ax is None :
891
+ ax = pylab .gca ()
892
+
893
+ if edgelist is None :
894
+ edgelist = G .edges ()
895
+
896
+ if not edgelist or len (edgelist ) == 0 : # no edges!
897
+ return None
898
+
899
+ # set edge positions
900
+ edge_pos = np .asarray ([(pos [e [0 ]], pos [e [1 ]]) for e in edgelist ])
901
+
902
+ if not cb .iterable (width ):
903
+ lw = (width ,)
904
+ else :
905
+ lw = width
906
+
907
+ if not isinstance (edge_color , str ) \
908
+ and cb .iterable (edge_color ) \
909
+ and len (edge_color ) == len (edge_pos ):
910
+ if np .alltrue ([isinstance (c , str )
911
+ for c in edge_color ]):
912
+ # (should check ALL elements)
913
+ # list of color letters such as ['k','r','k',...]
914
+ edge_colors = tuple ([colorConverter .to_rgba (c , alpha )
915
+ for c in edge_color ])
916
+ elif np .alltrue ([not isinstance (c , str )
917
+ for c in edge_color ]):
918
+ # If color specs are given as (rgb) or (rgba) tuples, we're OK
919
+ if np .alltrue ([cb .iterable (c ) and len (c ) in (3 , 4 )
920
+ for c in edge_color ]):
921
+ edge_colors = tuple (edge_color )
922
+ alpha = None
923
+ else :
924
+ # numbers (which are going to be mapped with a colormap)
925
+ edge_colors = None
926
+ else :
927
+ e_s = 'edge_color must consist of either color names or numbers'
928
+ raise ValueError (e_s )
929
+ else :
930
+ if len (edge_color ) == 1 :
931
+ edge_colors = (colorConverter .to_rgba (edge_color , alpha ),)
932
+ else :
933
+ e_s = 'edge_color must be a single color or list of exactly'
934
+ e_s += 'm colors where m is the number or edges'
935
+ raise ValueError (e_s )
936
+ edge_collection = LineCollection (edge_pos ,
937
+ colors = edge_colors ,
938
+ linewidths = lw ,
939
+ antialiaseds = (1 ,),
940
+ linestyle = style ,
941
+ transOffset = ax .transData ,
942
+ )
943
+
944
+ # Note: there was a bug in mpl regarding the handling of alpha values for
945
+ # each line in a LineCollection. It was fixed in matplotlib in r7184 and
946
+ # r7189 (June 6 2009). We should then not set the alpha value globally,
947
+ # since the user can instead provide per-edge alphas now. Only set it
948
+ # globally if provided as a scalar.
949
+ if cb .is_numlike (alpha ):
950
+ edge_collection .set_alpha (alpha )
951
+
952
+ # need 0.87.7 or greater for edge colormaps
953
+ if edge_colors is None :
954
+ if edge_cmap is not None :
955
+ assert (isinstance (edge_cmap , Colormap ))
956
+ edge_collection .set_array (np .asarray (edge_color ))
957
+ edge_collection .set_cmap (edge_cmap )
958
+ if edge_vmin is not None or edge_vmax is not None :
959
+ edge_collection .set_clim (edge_vmin , edge_vmax )
960
+ else :
961
+ edge_collection .autoscale ()
962
+ pylab .sci (edge_collection )
963
+
964
+ # else:
965
+ # sys.stderr.write(\
966
+ # """matplotlib version >= 0.87.7 required for colormapped edges.
967
+ # (version %s detected)."""%matplotlib.__version__)
968
+ # raise UserWarning(\
969
+ # """matplotlib version >= 0.87.7 required for colormapped edges.
970
+ # (version %s detected)."""%matplotlib.__version__)
971
+
972
+ arrow_collection = None
973
+
974
+ if G .is_directed () and arrows :
975
+
976
+ # a directed graph hack
977
+ # draw thick line segments at head end of edge
978
+ # waiting for someone else to implement arrows that will work
979
+ arrow_colors = (colorConverter .to_rgba ('k' , alpha ),)
980
+ a_pos = []
981
+ p = 1.0 - 0.25 # make head segment 25 percent of edge length
982
+ for src , dst in edge_pos :
983
+ x1 , y1 = src
984
+ x2 , y2 = dst
985
+ dx = x2 - x1 # x offset
986
+ dy = y2 - y1 # y offset
987
+ d = np .sqrt (float (dx ** 2 + dy ** 2 )) # length of edge
988
+ if d == 0 : # source and target at same position
989
+ continue
990
+ if dx == 0 : # vertical edge
991
+ xa = x2
992
+ ya = dy * p + y1
993
+ if dy == 0 : # horizontal edge
994
+ ya = y2
995
+ xa = dx * p + x1
996
+ else :
997
+ theta = np .arctan2 (dy , dx )
998
+ xa = p * d * np .cos (theta ) + x1
999
+ ya = p * d * np .sin (theta ) + y1
1000
+
1001
+ a_pos .append (((xa , ya ), (x2 , y2 )))
1002
+
1003
+ arrow_collection = LineCollection (a_pos ,
1004
+ colors = arrow_colors ,
1005
+ linewidths = [4 * ww for ww in lw ],
1006
+ antialiaseds = (1 ,),
1007
+ transOffset = ax .transData ,
1008
+ )
1009
+
1010
+ # update view
1011
+ minx = np .amin (np .ravel (edge_pos [:, :, 0 ]))
1012
+ maxx = np .amax (np .ravel (edge_pos [:, :, 0 ]))
1013
+ miny = np .amin (np .ravel (edge_pos [:, :, 1 ]))
1014
+ maxy = np .amax (np .ravel (edge_pos [:, :, 1 ]))
1015
+
1016
+ w = maxx - minx
1017
+ h = maxy - miny
1018
+ padx , pady = 0.05 * w , 0.05 * h
1019
+ corners = (minx - padx , miny - pady ), (maxx + padx , maxy + pady )
1020
+ ax .update_datalim (corners )
1021
+ ax .autoscale_view ()
1022
+
1023
+ edge_collection .set_zorder (1 ) # edges go behind nodes
1024
+ ax .add_collection (edge_collection )
1025
+ if arrow_collection :
1026
+ arrow_collection .set_zorder (1 ) # edges go behind nodes
1027
+ ax .add_collection (arrow_collection )
1028
+
1029
+ return ax
1030
+
1031
+
1032
+ > >> >> >> Updating older APIs .
841
1033
def mkgraph (cmat , threshold = 0.0 , threshold2 = None ):
842
1034
"""Make a weighted graph object out of an adjacency matrix.
843
1035
0 commit comments