# This script is part of navis (http://www.github.com/navis-org/navis).
# Copyright (C) 2018 Philipp Schlegel
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
""" Set of functions to interface with Cytoscape using its CyREST API. This
module requires py2cytoscape (https://github.com/cytoscape/py2cytoscape)
"""
import logging
import networkx as nx
import numpy as np
import pandas as pd
from py2cytoscape.data.cyrest_client import CyRestClient
# Set up logging
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)
if len(logger.handlers) == 0:
# Generate stream handler
sh = logging.StreamHandler()
sh.setLevel(logging.INFO)
# Create formatter and add it to the handlers
formatter = logging.Formatter(
'%(levelname)-5s : %(message)s (%(name)s)')
sh.setFormatter(formatter)
logger.addHandler(sh)
[docs]
def get_client():
"""Initialises connection with Cytoscape and returns client."""
return CyRestClient()
def get_navis_style():
"""Returns our default network style."""
cy = get_client()
all_styles = cy.style.get_all()
s = cy.style.create('navis')
# If the style already existed, return unchanged
if 'navis' in all_styles:
return s
# If we created the style from scratch, apply some basic settings
basic_settings = dict(
# You can set default values as key-value pairs.
NODE_FILL_COLOR='#FEC44F',
NODE_SIZE=18,
NODE_BORDER_WIDTH=7,
NODE_BORDER_COLOR='#999999',
NODE_LABEL_COLOR='#555555',
NODE_LABEL_FONT_SIZE=14,
NODE_LABEL_POSITION='S,NW,c,0.00,3.00',
EDGE_WIDTH=2,
EDGE_TRANSPARENCY=100,
EDGE_CURVED=True,
EDGE_BEND='0.728545744495502,-0.684997151948455,0.6456513365424503',
EDGE_UNSELECTED_PAINT='#CCCCCC',
EDGE_STROKE_UNSELECTED_PAINT='#333333',
EDGE_TARGET_ARROW_SHAPE='DELTA',
NETWORK_BACKGROUND_PAINT='#FFFFFF',
)
s.update_defaults(basic_settings)
return s
[docs]
def generate_network(x, layout='fruchterman-rheingold', apply_style=True,
clear_session=True):
"""Load network into Cytoscape.
Parameters
----------
x : networkX Graph | pandas.DataFrame
Network to export to Cytoscape. Can be:
1. NetworkX Graph e.g. from navis.networkx (preferred!)
2. Pandas DataFrame. Mandatory columns:
'source','target','interaction'
layout : str | None, optional
Layout to apply. Set to ``None`` to not apply any.
apply_style : bool, optional
If True will apply a "navis" style to the network.
clear_session : bool, optional
If True, will clear session before adding network.
Returns
-------
cytoscape Network
"""
# Initialise connection with Cytoscape
cy = get_client()
if layout not in cy.layout.get_all() + [None]:
raise ValueError('Unknown layout. Available options: '
', '.join(cy.layout.get_all()))
# Clear session
if clear_session:
cy.session.delete()
if isinstance(x, nx.Graph):
n = cy.network.create_from_networkx(x)
elif isinstance(x, np.ndarray):
n = cy.network.create_from_ndarray(x)
elif isinstance(x, pd.DataFrame):
n = cy.network.create_from_dataframe(x)
else:
raise TypeError(f'Unable to generate network from data of type "{type(x)}"')
if layout:
# Apply basic layout
cy.layout.apply(name=layout, network=n)
if apply_style:
# Get our default style
s = get_navis_style()
# Add some passthough mappings to the style
s.create_passthrough_mapping(
column='neuron_name', vp='NODE_LABEL', col_type='String')
max_edge_weight = n.get_edge_column('weight').max()
s.create_continuous_mapping(column='weight',
vp='EDGE_WIDTH',
col_type='Double',
points=[{'equal': '1.0', 'greater': '1.0', 'lesser': '1.0', 'value': 1.0},
{'equal': max_edge_weight / 3, 'greater': 1.0, 'lesser': max_edge_weight / 3, 'value': max_edge_weight}]
)
# Apply style
cy.style.apply(s, n)
return n