def __init__(self, queryset, label_threshold=2): self.label_threshold = label_threshold g = nx.DiGraph() for e in queryset: # create NX graph g.add_node(e.person, type='person', sector=str(e.person.sector), ego=e.person.ego) g.add_node(e.action, type='action', category=str(e.action.category)) for p in e.people.all(): g.add_node(p, type='person', sector=str(p.sector), ego=p.ego) # ego to alter g.add_edge(e.person, p) # alter to action g.add_edge(p, e.action) # ego to action g.add_edge(e.person, e.action, people=", ".join([str(p) for p in e.people.all()])) self.g = g self.h = Hiveplot() # sort nodes by degree self.k = list(nx.degree(g)) self.k.sort(key=lambda tup: tup[1]) self.actions = [] self.people = [] self.sectors = list(Sector.objects.all()) self.cats = list(Category.objects.all()) # create color palettes p = Palette("clarity") self.ac = p.random(no_of_colors=len(self.cats), shade=45) # sector colors self.sc = p.random(no_of_colors=len(self.sectors), shade=50)
"""Produces a plot visually the same as short_example, but uses modern features""" from __future__ import absolute_import, division, unicode_literals, print_function import random from math import pi from pyveplot import Hiveplot import networkx random.seed(1) # a network g = networkx.barabasi_albert_graph(50, 2, seed=2) # numbers use px units center = (200, 200) # our hiveplot object h = Hiveplot("modern_example.svg", center=center) axis0 = h.add_axis(start=center, end=(200, 100), stroke="grey") # polar coordinates (radius, angle): defaults to radians circle = 2 * pi # str units are interpreted correctly axis1 = h.add_axis_polar(end=("105pt", circle / 3), stroke="blue") axis2 = h.add_axis_polar(end=("5.82cm", 240), use_radians=False, stroke="black") # randomly distribute nodes in axes for n in g.nodes(): random.choice(h.axes).add_node(n, random.random()) for e in g.edges():
def test_short_example(tmpdir, request): fname = "short_example.svg" ref_fpath = os.path.join(TEST_DIR, fname) test_fpath = str(tmpdir.join(fname)) # seed must be the same random.seed(1) # a network g = networkx.barabasi_albert_graph(50, 2, seed=2) # our hiveplot object h = Hiveplot(test_fpath) # start end axis0 = Axis((200, 200), (200, 100), stroke="grey") axis1 = Axis((200, 200), (300, 300), stroke="blue") axis2 = Axis((200, 200), (10, 310), stroke="black") h.axes = [axis0, axis1, axis2] # randomly distribute nodes in axes for n in g.nodes(): node = Node(n) random.choice(h.axes).add_node(node, random.random()) for e in g.edges(): if (e[0] in axis0.nodes) and ( e[1] in axis1.nodes): # edges from axis0 to axis1 h.connect(axis0, e[0], 45, axis1, e[1], -45, stroke_width='0.34', stroke_opacity='0.4', stroke='purple') elif (e[0] in axis0.nodes) and ( e[1] in axis2.nodes): # edges from axis0 to axis2 h.connect(axis0, e[0], -45, axis2, e[1], 45, stroke_width='0.34', stroke_opacity='0.4', stroke='red') elif (e[0] in axis1.nodes) and ( e[1] in axis2.nodes): # edges from axis1 to axis2 h.connect(axis1, e[0], 15, axis2, e[1], -15, stroke_width='0.34', stroke_opacity='0.4', stroke='magenta') h.save(pretty=True) try: if sys.version_info >= (3, 6): assert_same_contents(ref_fpath, test_fpath) # elif (3, 0) < sys.version_info < (3, 6): else: # cannot check for exact identity in CPython < 3.6 due to # non-deterministic dict ordering assert_same_lines(ref_fpath, test_fpath) except AssertionError: if request.config.getoption("--dump"): ver = '.'.join(str(i) for i in sys.version_info) dt = datetime.now().isoformat().replace(':', '-') shutil.copyfile(test_fpath, os.path.join(TEST_DIR, '_'.join([ver, dt, fname]))) if sys.version_info < (3, 0): pytest.xfail( "Python 2 paths are visibly identical, but numerically different" ) raise
django.setup() from mm.models import Alter, Action, Sector, Agency, Networks n = Networks() n.update_alter_metrics() n.update_action_metrics() from math import sin, cos, radians from scale import Scale from pyveplot import Hiveplot, Node, Axis if args.sector == "all": h = Hiveplot('agency.svg') else: h = Hiveplot('%s.svg' % args.sector) def rotate(radius, angle, origin=(0, 0)): """ Returns a tuple of destination coordinates given a radius, angle and origin tuple """ return (origin[0] + round((radius * cos(radians(angle))), 2), origin[1] + round((radius * sin(radians(angle))), 2)) sector_color = {'Academia': 'blue', 'Gobierno': 'green', None: 'orange', 'Otros': 'purple',
def main(filename, alter_position, nb_axis): """Catch main function.""" try: fh = open(filename + ".edgelist", 'r') except IOError: print(filename + ".edgelist not found") raise g = nx.Graph() for line in fh.readlines(): (head, tail, *c) = line.split() g.add_edge(int(head, 16), int(tail, 16)) min_degree = 1 max_degree = min_degree degrees = {} for n in g: degrees[n] = nx.degree(g, n) max_degree = degrees[n] if degrees[n] > max_degree else max_degree values = list(degrees.values()) stats = {x: values.count(x) for x in values} stats = dict(collections.OrderedDict(sorted(stats.items()))) # make as many axes as requested radius = len(g.nodes()) margin = 100 center = (radius + margin, radius + margin) delta = float((math.pi * 2) / nb_axis) angle = 0 if alter_position is 0: fname = 'hiveplot' + str(nb_axis) + 'axes.svg' else: fname = 'hiveplot' + str(nb_axis) + 'axesAlteredPositions.svg' h = Hiveplot(fname) h.axes = [] print("Computing axes") for i in range(nb_axis): x = radius + margin + math.cos(angle) * radius y = radius + margin - math.sin(angle) * radius end = (x, y) axis = Axis( center, # start end, # end stroke="black", stroke_width=0.05) angle += delta h.axes.append(axis) c = 0 nbtot = 0 for x in stats: nbtot += x * stats[x] print("Computing nodes") for n in g.nodes(): nd = Node(n) deg = degrees[n] # use cumulated pop index = math.ceil((c / nbtot) * nb_axis) - 1 c += deg a = h.axes[int(index)] if alter_position is 0: node_pos = random.random() elif stats[deg] > 1: node_pos = random.random() * (math.sqrt(deg / max_degree)) else: node_pos = math.sqrt(deg / max_degree) a.add_node(nd, node_pos) red = str(int(255 / deg)) green = str(abs(int(math.cos(deg) * 255))) blue = str(abs(int(math.sin(deg) * 255))) color = "rgb(" + red + ", " + green + ", " + blue + ")" # alter node drawing after adding it to axis to keep coordinates nd.dwg = nd.dwg.circle(center=(nd.x, nd.y), r=deg / 3 + 2, fill=color, fill_opacity=0.6, stroke=random.choice( ['red', 'crimson', 'coral', 'purple']), stroke_width=0.1) print("Computing edges") opacity = 1 angle = 45 # edges from h.axes[0] to h.axes[1] for e in g.edges(): color = random.choice( ['blue', 'red', 'purple', 'green', 'magenta', 'cyan', 'crimson']) node0 = e[0] node1 = e[1] axis0 = axis1 = h.axes[0] for axe in h.axes: if node0 in axe.nodes: axis0 = axe if node1 in axe.nodes: axis1 = axe angle0 = (axis0.angle() if axis0.angle() >= 0 else axis0.angle() + 2 * math.pi) angle1 = axis1.angle() cond = (len(h.axes) - 2) * delta and angle0 - angle1 > 0 if axis0 == axis1: dest_angle0 = angle dest_angle1 = angle # don't why you have to compute like that but this is the only way # to have edges ploted properly. elif angle0 - angle1 <= cond: dest_angle0 = -angle dest_angle1 = angle else: dest_angle0 = angle dest_angle1 = -angle h.connect( axis0, node0, # angle of invisible axis for source control points dest_angle0, axis1, node1, # angle of invisible axis for target control points dest_angle1, stroke_width=0.1, # pass any SVG attributes to an edge stroke_opacity=opacity, stroke=color, ) print("Writing svg") h.save() print("Wrote file as ", fname)
# Setup django import django django.setup() from mm.models import Alter, Action, Category, Sector, Agency, Networks n = Networks() n.update_alter_metrics() n.update_action_metrics() from math import sin, cos, radians from scale import Scale from pyveplot import Hiveplot, Node, Axis if args.sector == "all": h = Hiveplot('agency_actioncats_joined_grey.svg') else: h = Hiveplot('%s_actioncats_joined_grey.svg' % args.sector) def rotate(radius, angle, origin=(0, 0)): """ Returns a tuple of destination coordinates given a radius, angle and origin tuple """ return (origin[0] + round( (radius * cos(radians(angle))), 2), origin[1] + round( (radius * sin(radians(angle))), 2)) sector_color = { 'Academia': 'blue', 'Gobierno': 'green',
for i in Ingredient.select(lambda i: 'animal origin' in i.tags)], reverse=True) def rotate(radius, angle, origin=(0, 0)): """ Returns a tuple of destination coordinates given a radius, angle and origin tuple """ return (origin[0] + round( (radius * cos(radians(angle))), 2), origin[1] + round( (radius * sin(radians(angle))), 2)) prefix = path.basename(args.gpickle.name).split('.')[0] hive_path = path.join("plots", "%s.svg" % prefix) h = Hiveplot(hive_path) offcenter = 50 center = (250, 250) rotation = 60 axis_vegan0_start = rotate(offcenter, angle=rotation - 30, origin=center) axis_vegan0_end = rotate(offcenter + len(vegan) * 4, angle=rotation - 30, origin=axis_vegan0_start) axis_vegan0 = Axis(axis_vegan0_start, axis_vegan0_end, stroke="darkgreen", stroke_opacity="1", stroke_width=3) axis_vegan1_start = rotate(offcenter, angle=rotation + 10, origin=center) axis_vegan1_end = rotate(offcenter + len(vegan) * 4,
class AgencyHiveplot: def __init__(self, queryset, label_threshold=2): self.label_threshold = label_threshold g = nx.DiGraph() for e in queryset: # create NX graph g.add_node(e.person, type='person', sector=str(e.person.sector), ego=e.person.ego) g.add_node(e.action, type='action', category=str(e.action.category)) for p in e.people.all(): g.add_node(p, type='person', sector=str(p.sector), ego=p.ego) # ego to alter g.add_edge(e.person, p) # alter to action g.add_edge(p, e.action) # ego to action g.add_edge(e.person, e.action, people=", ".join([str(p) for p in e.people.all()])) self.g = g self.h = Hiveplot() # sort nodes by degree self.k = list(nx.degree(g)) self.k.sort(key=lambda tup: tup[1]) self.actions = [] self.people = [] self.sectors = list(Sector.objects.all()) self.cats = list(Category.objects.all()) # create color palettes p = Palette("clarity") self.ac = p.random(no_of_colors=len(self.cats), shade=45) # sector colors self.sc = p.random(no_of_colors=len(self.sectors), shade=50) def add_node_to_axis(self, v, axis, circle_color, fill_opacity=0.7): # create node object node = Node(radius=self.g.degree(v), label="") # add it to axis axis.add_node(v, node) # once it has x, y coordinates, add a circle node.add_circle(fill=circle_color, stroke=circle_color, stroke_width=0.1, fill_opacity=fill_opacity) if axis.angle < 180: orientation = -1 scale = 0.6 else: orientation = 1 scale = 0.35 # also add a label if self.g.degree(v) > self.label_threshold: node.add_label("%s k=%s" % (v, self.g.degree(v)), angle=axis.angle + 90 * orientation, scale=scale) def add_ego_axis(self): axis = Axis(start=40, angle=90, stroke=ego_color, stroke_width=1.1) for v in self.k: v = v[0] if ('ego' in self.g.nodes[v] and self.g.nodes[v]['ego'] is True): self.add_node_to_axis(v, axis, 'blue') # sector colors self.h.axes.append(axis) def add_sector_axes(self): end = 40 for sector in self.sectors: sector_color = self.sc[self.sectors.index(sector)] axis = Axis(start=end, angle=90 + 120, stroke=sector_color, stroke_width=1.1) for v in self.k: v = v[0] if ('ego' in self.g.nodes[v] and self.g.nodes[v]['ego'] is False and self.g.nodes[v]['sector'] == str(sector)): self.add_node_to_axis(v, axis, circle_color=sector_color) axis.auto_place_nodes() if axis.length() > 0: end = axis.end + 30 axis.name = sector self.h.axes.append(axis) self.people.append(axis) def add_actioncat_axes(self): end = 40 for cat in self.cats: cat_color = self.ac[self.cats.index(cat)] axis = Axis(start=end, angle=90 + 120 + 120, stroke=cat_color, stroke_width=1.1) for v in self.k: v = v[0] if (self.g.nodes[v]['type'] == 'action' and self.g.nodes[v]['category'] == str(cat)): self.add_node_to_axis(v, axis, circle_color=cat_color) axis.auto_place_nodes() if axis.length() > 0: end = axis.end + 30 axis.name = cat self.h.axes.append(axis) self.actions.append(axis) def connect_axes(self): for axis in self.actions: n = self.h.axes.index(axis) cat_color = self.ac[self.cats.index(axis.name)] self.h.connect_axes(self.h.axes[n], self.h.axes[0], self.g.edges, stroke_width=0.5, stroke=cat_color) for axis in self.people: n = self.h.axes.index(axis) sector_color = self.sc[self.sectors.index(axis.name)] self.h.connect_axes(self.h.axes[0], self.h.axes[n], self.g.edges, stroke_width=0.5, stroke=sector_color) for p in self.people: n = self.h.axes.index(p) sector_color = self.sc[self.sectors.index(p.name)] for a in self.actions: m = self.h.axes.index(a) cat_color = self.ac[self.cats.index(a.name)] self.h.connect_axes(self.h.axes[n], self.h.axes[m], self.g.edges, stroke_width=0.5, stroke=sector_color) def save(self, filename): self.h.save(filename) tmp_file = tempfile.SpooledTemporaryFile() pyveplot.dwg = svgwrite.Drawing(tmp_file)