def test_metadata_double_name(self, mock_etl2, mock_open): edges = triangleEdges.copy() edges['a1'] = triangleNodes.a1.map(lambda x: x+10) graphistry.bind(source='src', destination='dst', node='id').plot(edges, triangleNodes) dataset = mock_etl2.call_args[0][0] self.assertIn('a1', dataset['attributes']['nodes']) self.assertIn('a1', dataset['attributes']['edges'])
def test_metadata_no_nat(self, mock_etl2, mock_open): edges = triangleEdges.copy() edges['testDate'] = triangleNodes.a1.map(lambda x: None if x == 1 else datetime.datetime.now()) edges['testDate2'] = triangleNodes.a1.map(lambda x: None) edges['testDate'] = pandas.to_datetime(edges.testDate, errors='ignore') edges['testDate2'] = pandas.to_datetime(edges.testDate2, errors='ignore') graphistry.bind(source='src', destination='dst', node='id').plot(edges) dataset = mock_etl2.call_args[0][0] for attrib in ['testDate', 'testDate2']: for entry in list(dataset['attributes']['edges'][attrib]['aggregations'].values()): self.assertFalse(isinstance(entry, pandas.tslib.NaTType))
def test_metadata_mandatory_fields(self, mock_etl2, mock_open): graphistry.bind(source='src', destination='dst').plot(triangleEdges) dataset = mock_etl2.call_args[0][0] self.assertListEqual(list(dataset['attributes']['nodes']), [nid]) self.assertListEqual(list(dataset['attributes']['edges']), []) self.assertEqual(dataset['encodings']['nodes'], { 'pointTitle': {'attributes': [nid]}, 'nodeId': {'attributes': [nid]} }) self.assertEqual(dataset['encodings']['edges'], { 'source': {'attributes': ['src']}, 'destination': {'attributes': ['dst']} })
def test_empty_graph(self, mock_error, mock_etl2, mock_warn, mock_open): mock_error.side_effect = ValueError('error') plotter = graphistry.bind(source='src', destination='dst') with self.assertRaises(ValueError): plotter.plot(pandas.DataFrame([])) self.assertFalse(mock_etl2.called) self.assertTrue(mock_error.called)
def test_no_src_dst(self, mock_etl2, mock_warn, mock_open): with self.assertRaises(ValueError): graphistry.bind().plot(triangleEdges) with self.assertRaises(ValueError): graphistry.bind(source='src').plot(triangleEdges) with self.assertRaises(ValueError): graphistry.bind(destination='dst').plot(triangleEdges) with self.assertRaises(ValueError): graphistry.bind(source='doesnotexist', destination='dst').plot(triangleEdges)
def test_metadata_no_nan(self, mock_etl2, mock_open): edges = triangleEdges.copy() edges['testNone'] = triangleNodes.a1.map(lambda x: numpy.nan) edges['testNone'] = pandas.to_numeric(edges.testNone, errors='ignore') edges['testInt'] = triangleNodes.a1.map(lambda x: numpy.nan if x%2 == 1 else 0) edges['testFloat'] = triangleNodes.a1.map(lambda x: numpy.nan if x%2 == 1 else 0.5) edges['testString'] = triangleNodes.a1.map(lambda x: numpy.nan if x%2 == 1 else 'foo') edges['testBool'] = triangleNodes.a1.map(lambda x: numpy.nan if x%2 == 1 else True) graphistry.bind(source='src', destination='dst', node='id').plot(edges) dataset = mock_etl2.call_args[0][0] for attrib in ['testInt', 'testFloat', 'testString', 'testBool', 'testNone']: for entry in list(dataset['attributes']['edges'][attrib]['aggregations'].values()): if entry is None or isinstance(entry, str): pass else: self.assertFalse(numpy.isnan(entry))
def draw_graph(graph, nodes=None): ''' 采用pygraphistry 来绘制网络图,节点颜色目前还不能超过12种 :param graph: networkx.Graph/DiGraph :param nodes: DataFrame,如果需要按社区颜色绘制,请传入带有社区信息的节点表, ['Id','modulraity_class'] :return: None ''' graphistry.register(key='contact pygraphistry for api key') ploter = graphistry.bind(source='Source', destination='Target').graph(graph) if nodes is not None: ploter = ploter.bind(node='Id', point_color='modularity_class').nodes(nodes) ploter.plot() return None
def test_api3_cudf_to_arrow_memoization_forgets(self): maybe_cudf = None try: import cudf maybe_cudf = cudf except ImportError: 1 if maybe_cudf is None: return plotter = graphistry.bind() df = maybe_cudf.DataFrame({'x': [0]}) arr1 = plotter._table_to_arrow(df) for i in range(1, 110): plotter._table_to_arrow(maybe_cudf.DataFrame({'x': [i]})) assert not (arr1 is plotter._table_to_arrow(df))
def test_networkx2igraph(self): import networkx as nx ng = nx.complete_graph(3) [x, y] = [int(x) for x in nx.__version__.split('.')] if x == 1: nx.set_node_attributes(ng, 'vattrib', 0) nx.set_edge_attributes(ng, 'eattrib', 1) else: nx.set_node_attributes(ng, 0, 'vattrib') nx.set_edge_attributes(ng, 1, 'eattrib') (e, n) = graphistry.bind(source='src', destination='dst').networkx2pandas(ng) edges = pd.DataFrame({ 'dst': { 0: 1, 1: 2, 2: 2 }, 'src': { 0: 0, 1: 0, 2: 1 }, 'eattrib': { 0: 1, 1: 1, 2: 1 } }) nodes = pd.DataFrame({ '__nodeid__': { 0: 0, 1: 1, 2: 2 }, 'vattrib': { 0: 0, 1: 0, 2: 0 } }) assertFrameEqual(e, edges) assertFrameEqual(n, nodes)
def test_igraph2pandas(self): ig = igraph.Graph.Tree(4, 2) ig.vs['vattrib'] = 0 ig.es['eattrib'] = 1 (e, n) = graphistry.bind(source='src', destination='dst').igraph2pandas(ig) edges = pandas.DataFrame({ 'dst': {0: 1, 1: 2, 2: 3}, 'src': {0: 0, 1: 0, 2: 1}, 'eattrib': {0: 1, 1: 1, 2: 1} }) nodes = pandas.DataFrame({ '__nodeid__': {0: 0, 1: 1, 2: 2, 3: 3}, 'vattrib': {0: 0, 1: 0, 2: 0, 3: 0} }) assertFrameEqual(e, edges) assertFrameEqual(n, nodes)
def test_networkx2igraph(self): ng = networkx.complete_graph(3) networkx.set_node_attributes(ng, 'vattrib', 0) networkx.set_edge_attributes(ng, 'eattrib', 1) (e, n) = graphistry.bind(source='src', destination='dst').networkx2pandas(ng) edges = pandas.DataFrame({ 'dst': {0: 1, 1: 2, 2: 2}, 'src': {0: 0, 1: 0, 2: 1}, 'eattrib': {0: 1, 1: 1, 2: 1} }) nodes = pandas.DataFrame({ '__nodeid__': {0: 0, 1: 1, 2: 2}, 'vattrib': {0: 0, 1: 0, 2: 0} }) assertFrameEqual(e, edges) assertFrameEqual(n, nodes)
def test_igraph2pandas(self): ig = igraph.Graph.Tree(4, 2) ig.vs['vattrib'] = 0 ig.es['eattrib'] = 1 (e, n) = graphistry.bind(source='src', destination='dst').igraph2pandas(ig) edges = pandas.DataFrame({ 'dst': {0: 1, 1: 2, 2: 3}, 'src': {0: 0, 1: 0, 2: 1}, 'eattrib': {0: 1, 1: 1, 2: 1} }) nodes = pandas.DataFrame({ '__nodeid__': {0: 0, 1: 1, 2: 2, 3: 3}, 'vattrib': {0: 0, 1: 0, 2: 0, 3: 0} }) assertFrameEqual(e, edges) assertFrameEqual(n, nodes)
def test_api3_cudf_to_arrow_memoization(self): maybe_cudf = None try: import cudf maybe_cudf = cudf except ImportError: 1 if maybe_cudf is None: return plotter = graphistry.bind() df = maybe_cudf.DataFrame({'x': [1]}) arr1 = plotter._table_to_arrow(df) arr2 = plotter._table_to_arrow(df) assert isinstance(arr1, pa.Table) assert arr1 is arr2 arr3 = plotter._table_to_arrow(maybe_cudf.DataFrame({'x': [1]})) assert arr1 is arr3
def modularity(cluster_result, edgedata=None, graph=None, directed=True, edge_weight='Weight'): ''' :param cluster_result: 聚类结果,参考gephi输出的表,[Id,modulraity_class] :param edgedata: 边数据,与graph给定其中一个 :param graph: networkx中的Graph/DiGraph :param directed: 是否为有向图 :param edge_weight: None/str, 计算模块度是否使用边的权重,如果使用,给定边权重的name 例如edge_weight='Weight' 如果不使用,请给定为None :return: Q值 ps: 1.edgedata 和 graph 至少要给定一个 2.与gephi中计算的模块度结果已经对比过了,结果一致 ''' if edgedata is None and graph is not None: edgedata = NetworkUnity.networkx2pandas(graph) gr = graphistry.bind(source='Source', destination='Target', node='Id', edge_weight=edge_weight) ig = gr.pandas2igraph(edgedata, directed=directed) nodes = pd.DataFrame(list(ig.vs['Id']), columns=['Id']) community_data = pd.merge(nodes, cluster_result, left_on='Id', right_on='Id', how='left') if edge_weight is None: Q = ig.modularity(list(community_data['modularity_class']), weights=None) else: Q = ig.modularity(list(community_data['modularity_class']), weights=list(ig.es[edge_weight])) return Q
def test_au_e_enc_full(self): g = graphistry.bind(source='s', destination='d', edge_color='c', edge_title='t', edge_label='l', edge_weight='w', edge_opacity='o', edge_icon='i', edge_size='s', edge_source_color='sc', edge_destination_color='dc') g = g.encode_edge_color('c', ["green"], as_categorical=True) au = ArrowUploader() assert au.g_to_edge_encodings(g) == { 'bindings': { 'source': 's', 'destination': 'd', 'edge_color': 'c', 'edge_title': 't', 'edge_label': 'l', 'edge_weight': 'w', 'edge_opacity': 'o', 'edge_icon': 'i', 'edge_size': 's', 'edge_source_color': 'sc', 'edge_destination_color': 'dc' }, 'complex': { 'default': { 'edgeColorEncoding': { 'graphType': 'edge', 'encodingType': 'color', 'attribute': 'c', 'variation': 'categorical', 'colors': ['green'] } } } }
def test_networkx2igraph(self): ng = networkx.complete_graph(3) networkx.set_node_attributes(ng, 'vattrib', 0) networkx.set_edge_attributes(ng, 'eattrib', 1) (e, n) = graphistry.bind(source='src', destination='dst').networkx2pandas(ng) edges = pandas.DataFrame({ 'dst': { 0: 1, 1: 2, 2: 2 }, 'src': { 0: 0, 1: 0, 2: 1 }, 'eattrib': { 0: 1, 1: 1, 2: 1 } }) nodes = pandas.DataFrame({ '__nodeid__': { 0: 0, 1: 1, 2: 2 }, 'vattrib': { 0: 0, 1: 0, 2: 0 } }) assertFrameEqual(e, edges) assertFrameEqual(n, nodes)
def test_au_n_enc_full(self): g = graphistry.bind(node='n', point_color='c', point_size='s', point_title='t', point_label='l', point_weight='w', point_opacity='o', point_icon='i', point_x='x', point_y='y') g = g.encode_point_color('c', ["green"], as_categorical=True) au = ArrowUploader() assert au.g_to_node_encodings(g) == { 'bindings': { 'node': 'n', 'node_color': 'c', 'node_size': 's', 'node_title': 't', 'node_label': 'l', 'node_weight': 'w', 'node_opacity': 'o', 'node_icon': 'i', 'node_x': 'x', 'node_y': 'y', }, 'complex': { 'default': { 'pointColorEncoding': { 'graphType': 'point', 'encodingType': 'color', 'attribute': 'c', 'variation': 'categorical', 'colors': ['green'] } } } }
def test_ipython(self, mock_util, mock_post, mock_open): widget = graphistry.bind(source='src', destination='dst').plot(triangleEdges) self.assertIsInstance(widget, IPython.core.display.HTML)
def test_point_color(self): assert graphistry.bind().encode_point_color('z')._point_color == 'z' assert graphistry.bind().encode_point_color('z', ["red", "blue"], as_continuous=True)._complex_encodings \ == { **TestPlotterEncodings.COMPLEX_EMPTY, 'node_encodings': { 'default': { 'pointColorEncoding': { 'graphType': 'point', 'encodingType': 'color', 'attribute': 'z', 'variation': 'continuous', 'colors': ['red', 'blue'] } }, 'current': {} } } assert graphistry.bind().encode_point_color('z', ["red", "blue"], as_categorical=True)._complex_encodings \ == { **TestPlotterEncodings.COMPLEX_EMPTY, 'node_encodings': { 'default': { 'pointColorEncoding': { 'graphType': 'point', 'encodingType': 'color', 'attribute': 'z', 'variation': 'categorical', 'colors': ['red', 'blue'] } }, 'current': {} } } assert graphistry.bind().encode_point_color('z', categorical_mapping={'truck': 'red'})._complex_encodings \ == { **TestPlotterEncodings.COMPLEX_EMPTY, 'node_encodings': { 'default': { 'pointColorEncoding': { 'graphType': 'point', 'encodingType': 'color', 'attribute': 'z', 'variation': 'categorical', 'mapping': { 'categorical': { 'fixed': { 'truck': 'red' } } } } }, 'current': {} } } assert graphistry.bind().encode_point_color('z', categorical_mapping={'truck': 'red'}, default_mapping='blue')._complex_encodings \ == { **TestPlotterEncodings.COMPLEX_EMPTY, 'node_encodings': { 'default': { 'pointColorEncoding': { 'graphType': 'point', 'encodingType': 'color', 'attribute': 'z', 'variation': 'categorical', 'mapping': { 'categorical': { 'fixed': { 'truck': 'red' }, 'other': 'blue' } } } }, 'current': {} } }
def test_bind_edges_nodes(self, mock_etl2, mock_open): plotter0 = graphistry.bind(source='src').bind(destination='dst') plotter1 = plotter0.bind(node='id').bind(point_title='a2') plotter1.edges(triangleEdges).nodes(triangleNodes).plot() self.assertTrue(mock_etl2.called)
def test_metadata_mandatory_fields(self, mock_etl2, mock_open): edges = triangleEdges.copy() edges['ustring'] = [u'abcdef', u'тйîbàüd', u'♜ ♞ ♝ ♛ ♚ ♝ ♞ ♜'] graphistry.bind(source='src', destination='dst').plot(edges) self.assertTrue(mock_etl2.called)
def test_set_mode(self): assert graphistry.bind().encode_point_color('z', categorical_mapping={'a': 'b'})._complex_encodings \ == { **TestPlotterEncodings.COMPLEX_EMPTY, 'node_encodings': { 'default': { 'pointColorEncoding': { 'graphType': 'point', 'encodingType': 'color', 'attribute': 'z', 'variation': 'categorical', 'mapping': { 'categorical': {'fixed': { 'a': 'b' } } } } }, 'current': {} } } assert graphistry.bind().encode_point_color('z', categorical_mapping={'a': 'b'}, for_default=False, for_current=False)._complex_encodings \ == { **TestPlotterEncodings.COMPLEX_EMPTY, 'node_encodings': { 'default': {}, 'current': {} } } assert graphistry.bind().encode_point_color('z', categorical_mapping={'a': 'b'}, for_default=True, for_current=False)._complex_encodings \ == { **TestPlotterEncodings.COMPLEX_EMPTY, 'node_encodings': { 'default': { 'pointColorEncoding': { 'graphType': 'point', 'encodingType': 'color', 'attribute': 'z', 'variation': 'categorical', 'mapping': { 'categorical': {'fixed': { 'a': 'b' } } } } }, 'current': {} } } assert graphistry.bind().encode_point_color('z', categorical_mapping={'a': 'b'}, for_default=False, for_current=True)._complex_encodings \ == { **TestPlotterEncodings.COMPLEX_EMPTY, 'node_encodings': { 'default': { }, 'current': { 'pointColorEncoding': { 'graphType': 'point', 'encodingType': 'color', 'attribute': 'z', 'variation': 'categorical', 'mapping': { 'categorical': { 'fixed': { 'a': 'b' } } } } } } } assert graphistry.bind().encode_point_color('z', categorical_mapping={'a': 'b'}, for_default=True, for_current=True)._complex_encodings \ == { **TestPlotterEncodings.COMPLEX_EMPTY, 'node_encodings': { 'default': { 'pointColorEncoding': { 'graphType': 'point', 'encodingType': 'color', 'attribute': 'z', 'variation': 'categorical', 'mapping': { 'categorical': { 'fixed': { 'a': 'b' } } } } }, 'current': { 'pointColorEncoding': { 'graphType': 'point', 'encodingType': 'color', 'attribute': 'z', 'variation': 'categorical', 'mapping': { 'categorical': { 'fixed': { 'a': 'b' } } } } } } }
def test_no_nodeid(self, mock_etl2, mock_warn, mock_open): plotter = graphistry.bind(source='src', destination='dst') with self.assertRaises(ValueError): plotter.plot(triangleEdges, triangleNodes)
def test_bind_description(self): plotter = graphistry.bind().description('d') assert plotter._description == 'd'
def test_edge_icon(self): assert graphistry.bind().encode_edge_icon('z')._edge_icon == 'z'
def test_au_n_enc_mt(self): g = graphistry.bind() au = ArrowUploader() assert au.g_to_node_encodings(g) == {'bindings': {}}
def test_ipython(self, mock_util, mock_post, mock_open): widget = graphistry.bind(source='src', destination='dst').plot(triangleEdges) self.assertIsInstance(widget, IPython.core.display.HTML)
def test_pandas2igraph(self): plotter = graphistry.bind(source='src', destination='dst', node='id') ig = plotter.pandas2igraph(triangleEdges) (e, n) = plotter.igraph2pandas(ig) assertFrameEqual(e, triangleEdges[['src', 'dst']]) assertFrameEqual(n, triangleNodes[['id']])
def test_bind_edges_nodes(self, mock_etl2, mock_open): plotter0 = graphistry.bind(source='src').bind(destination='dst') plotter1 = plotter0.bind(node='id').bind(point_title='a2') plotter1.edges(triangleEdges).nodes(triangleNodes).plot() self.assertTrue(mock_etl2.called)
def test_bind_chain(self, mock_etl2, mock_open): plotter0 = graphistry.bind(source='caca').bind(destination='dst', source='src') plotter0.plot(triangleEdges) self.assertTrue(mock_etl2.called)
def test_point_size(self): assert graphistry.bind().encode_point_size('z')._point_size == 'z'
def test_table_to_pandas_from_none(self): plotter = graphistry.bind() assert plotter._table_to_pandas(None) is None
def test_point_icon(self): assert graphistry.bind().encode_point_icon('z')._point_icon == 'z'
def test_table_to_pandas_from_pandas(self): plotter = graphistry.bind() df = pd.DataFrame({'x': []}) assert isinstance(plotter._table_to_pandas(df), pd.DataFrame)
def test_edge_color(self): assert graphistry.bind().encode_edge_color('z')._edge_color == 'z'
def test_table_to_arrow_from_none(self): plotter = graphistry.bind() assert plotter._table_to_arrow(None) is None
def test_composition(self): # chaining + overriding out = graphistry.bind()\ .encode_point_size('z', categorical_mapping={'m': 2})\ .encode_point_color('z', categorical_mapping={'a': 'b'}, for_current=True)\ .encode_point_color('z', categorical_mapping={'a': 'b2'})\ .encode_edge_color( 'z', categorical_mapping={'x': 'y'}, for_current=True)\ ._complex_encodings assert out['edge_encodings']['default'] == { 'edgeColorEncoding': { 'graphType': 'edge', 'encodingType': 'color', 'attribute': 'z', 'variation': 'categorical', 'mapping': { 'categorical': { 'fixed': { 'x': 'y' } } } } } assert out['edge_encodings']['current'] == { 'edgeColorEncoding': { 'graphType': 'edge', 'encodingType': 'color', 'attribute': 'z', 'variation': 'categorical', 'mapping': { 'categorical': { 'fixed': { 'x': 'y' } } } } } assert out['node_encodings']['default'] == { 'pointSizeEncoding': { 'graphType': 'point', 'encodingType': 'size', 'attribute': 'z', 'variation': 'categorical', 'mapping': { 'categorical': { 'fixed': { 'm': 2 } } } }, 'pointColorEncoding': { 'graphType': 'point', 'encodingType': 'color', 'attribute': 'z', 'variation': 'categorical', 'mapping': { 'categorical': { 'fixed': { 'a': 'b2' } } } } } assert out['node_encodings']['current'] == { 'pointColorEncoding': { 'graphType': 'point', 'encodingType': 'color', 'attribute': 'z', 'variation': 'categorical', 'mapping': { 'categorical': { 'fixed': { 'a': 'b' } } } } }
def test_table_to_arrow_from_arrow(self): plotter = graphistry.bind() df = pd.DataFrame({'x': []}) arr = pa.Table.from_pandas(df) assert isinstance(plotter._table_to_arrow(arr), pa.Table)
def test_pandas2igraph(self): plotter = graphistry.bind(source='src', destination='dst', node='id') ig = plotter.pandas2igraph(triangleEdges) (e, n) = plotter.igraph2pandas(ig) assertFrameEqual(e, triangleEdges[['src', 'dst']]) assertFrameEqual(n, triangleNodes[['id']])
def test_unknown_col_nodes(self, mock_etl2, mock_warn, mock_open): plotter = graphistry.bind(source='src', destination='dst', node='id', point_title='doesnotexist') plotter.plot(triangleEdges, triangleNodes) self.assertTrue(mock_etl2.called) self.assertTrue(mock_warn.called)
def test_bind_chain(self, mock_etl2, mock_open): plotter0 = graphistry.bind(source='caca').bind(destination='dst', source='src') plotter0.plot(triangleEdges) self.assertTrue(mock_etl2.called)
def test_init_mt(self): assert graphistry.bind( )._complex_encodings == TestPlotterEncodings.COMPLEX_EMPTY
def test_init(self): g = graphistry.bind() assert g._style == None
def test_bind_edges(self, mock_etl2, mock_warn, mock_open): plotter = graphistry.bind(source='src', destination='dst', edge_title='src') plotter.plot(triangleEdges) self.assertTrue(mock_etl2.called) self.assertFalse(mock_warn.called)
def test_bind_name(self): plotter = graphistry.bind().name('n') assert plotter._name == 'n'
def test_no_ipython(self, mock_post, mock_open): url = graphistry.bind(source='src', destination='dst').plot(triangleEdges) self.assertIn('fakedatasetname', url) self.assertIn('faketoken', url) self.assertTrue(mock_open.called) self.assertTrue(mock_post.called)