예제 #1
0
def returnDataCirc():
    """
        API route - data for the simple circular layout, can apply order optimisation method before returning order
    """

    # Get the data from the db
    sets = getData(request)
    # Filter for only values of length 2
    # for biconnected graph this is sufficient as all supersets (i.e. orders greater than 2) must contain these subsets
    sets = [s for s in sets if len(s['labels']) == 2]
    # Apply order optimisation
    if "order_opt" in request.args:
        if request.args['order_opt'] == "avsdf":
            order = AVSDF([s['labels'] for s in sets],
                          local_adjusting=False).run_AVSDF()
        elif request.args['order_opt'] == "avsdf_la":
            order = AVSDF([s['labels'] for s in sets],
                          local_adjusting=True).run_AVSDF()
        elif request.args['order_opt'] == "bb":
            order = BaurBrandes([s['labels'] for s in sets],
                                local_adjusting=False).run_bb()
        elif request.args['order_opt'] == "bb_la":
            order = BaurBrandes([s['labels'] for s in sets],
                                local_adjusting=True).run_bb()
        else:
            abort(500, description="Optimisation type not recognised")
    else:
        if 'majmin_agg' in request.args:
            if request.args['majmin_agg']:
                order = default_order_agg
            else:
                order = default_order
        else:
            order = default_order

    return jsonify({"sets": sets, "order": order})
예제 #2
0
 def test_degree3(self):
     self.assertEqual(AVSDF(self.edge_list3)._degree("A"), 7)
예제 #3
0
 def test_degree2_2(self):
     self.assertEqual(AVSDF(self.edge_list2)._degree(55), 0)
예제 #4
0
 def test_degree2(self):
     self.assertEqual(AVSDF(self.edge_list2)._degree("D"), 2)
예제 #5
0
 def test_degree1(self):
     self.assertEqual(AVSDF(self.edge_list1)._degree("B"), 1)
예제 #6
0
 def test_adj_vertex3(self):
     self.assertCountEqual(
         AVSDF(self.edge_list3)._adjacent_vertices("B"), ["B", "H", "A"])
예제 #7
0
 def test_adj_vertex2(self):
     self.assertCountEqual(
         AVSDF(self.edge_list2)._adjacent_vertices("D"), ["G", "H", "D"])
예제 #8
0
 def test_adj_vertex1(self):
     self.assertCountEqual(
         AVSDF(self.edge_list1)._adjacent_vertices("C"), [])
예제 #9
0
 def test_adj_edges3(self):
     self.assertCountEqual(
         AVSDF(self.edge_list3)._adjacent_edges("A"),
         [["A", "B"], ["A", "C"], ["A", "D"], ["A", "E"], ["A", "F"],
          ["A", "G"], ["A", "H"]])
예제 #10
0
 def test_adj_edges2(self):
     self.assertCountEqual(
         AVSDF(self.edge_list2)._adjacent_edges("H"),
         [["H", "D"], ["B", "H"]])
예제 #11
0
 def test_adj_edges1_1(self):
     self.assertEqual(AVSDF(self.edge_list1)._adjacent_edges("C"), [])
예제 #12
0
 def test_adj_edges1(self):
     self.assertEqual(
         AVSDF(self.edge_list1)._adjacent_edges("A"), [["A", "B"]])
예제 #13
0
 def test_edge_crossings_number3(self):
     self.assertEqual(
         AVSDF([])._count_crossings_edge(self.order3, self.edge_list3,
                                         ["A", "C"]), 1)
예제 #14
0
 def test_edge_crossings_number2(self):
     self.assertEqual(
         AVSDF([])._count_crossings_edge(self.order2, self.edge_list2,
                                         ["H", "B"]), 0)
예제 #15
0
 def test_total_crossing_number_count3(self):
     self.assertEqual(
         AVSDF([])._count_all_crossings(self.order3, self.edge_list3), 5)
예제 #16
0
def returnCircClust():
    """
        API route - get data for circular chart with clustered bundling
        Applies transformation and clustering to similar edges based on node positions
        to allow edges to be bundled together
    """
    # Get data from db
    sets = getData(request)
    # Filter for doubletons
    sets = [s for s in sets if len(s['labels']) == 2]

    # Apply order optimisation
    if "order_opt" in request.args:
        if request.args['order_opt'] == "avsdf":
            order = AVSDF([s['labels'] for s in sets],
                          local_adjusting=False).run_AVSDF()
        elif request.args['order_opt'] == "avsdf_la":
            order = AVSDF([s['labels'] for s in sets],
                          local_adjusting=True).run_AVSDF()
        elif request.args['order_opt'] == "bb":
            order = BaurBrandes([s['labels'] for s in sets],
                                local_adjusting=False).run_bb()
        elif request.args['order_opt'] == "bb_la":
            order = BaurBrandes([s['labels'] for s in sets],
                                local_adjusting=True).run_bb()
        else:
            abort(500, description="Optimisation type not recognised")
    else:
        if 'majmin_agg' in request.args:
            if request.args['majmin_agg']:
                order = default_order_agg
            else:
                order = default_order
        else:
            order = default_order

    # Leave only maj/min chords to see what it looks like clutter wise
    #sets = [s for s in sets if "7" not in "".join(s['labels'])]
    #order = [o for o in order if "7" not in o]

    # Map vertex labels to order index
    order_map = {k: i for i, k in enumerate(order)}

    # Dataframe (easier to manipulate/apply clustering)
    df = pd.DataFrame(sets)

    # Sort by order as clustering will be affected by the order of the vertices in edge definitions
    df['labels'] = df['labels'].apply(lambda x: sorted(
        x, key=lambda x: (np.sin(
            (order_map[x] / len(order_map)) * 2 * np.pi))))
    # Sort set labels in order
    s_labels_ordered = list(df['labels'])
    # Apply sin/cos transformation (takes into account circular nature of data)
    df['sin1'] = df['labels'].apply(lambda x: np.sin(
        (order_map[x[0]] / len(order_map)) * 2 * np.pi))
    df['cos1'] = df['labels'].apply(lambda x: np.cos(
        (order_map[x[0]] / len(order_map)) * 2 * np.pi))
    df['sin2'] = df['labels'].apply(lambda x: np.sin(
        (order_map[x[1]] / len(order_map)) * 2 * np.pi))
    df['cos2'] = df['labels'].apply(lambda x: np.cos(
        (order_map[x[1]] / len(order_map)) * 2 * np.pi))

    # Apply clustering to edges based on node values
    #labs = KMeans(n_clusters=40,random_state=44).fit(df[['sin1','cos1','sin2','cos2']]).labels_
    labs = AgglomerativeClustering(n_clusters=None, distance_threshold=1).fit(
        df[['sin1', 'cos1', 'sin2', 'cos2']]).labels_

    # Add cluster label to returned JSON
    sets_w_lab = []
    for set_lab, s, lab in zip(s_labels_ordered, sets, labs):
        sets_w_lab.append({
            "labels": set_lab,
            "values": s['values'],
            "tag": s['tag'],
            "km_label": int(lab)
        })

    return jsonify({"sets": sets_w_lab, "order": order})