Custom Graphics and Labels

Open In Colab

by Kozo Nishida, Kristina Hanspers, Alexander Pico, Barry Demchak

py4cytoscape 0.0.11

This notebook illustrates how Cytoscape’s Custom Graphics can be used to add graphs, charts and other graphics to node, and how to combine Custom Graphics with the enhancedGraphics app for specialized visualizations.

Prerequisites

In addition to this package (py4cytoscape), you will need:

  • Cytoscape 3.8 or greater, which can be downloaded from https://cytoscape.org/download.html. Simply follow the installation instructions on screen.

  • Complete installation wizard

  • Launch Cytoscape

  • If your Cytoscape is 3.8.2 or earlier, install FileTransfer App (Follow here to do it.)

NOTE: To run this notebook, you must manually start Cytoscape first – don’t proceed until you have started Cytoscape.

Setup required only in a remote notebook environment

If you’re using a remote Jupyter Notebook environment such as Google Colab, run the cell below. (If you’re running a local Jupyter Notebook server on the desktop machine same with Cytoscape, you don’t need to do that.)

[ ]:
_PY4CYTOSCAPE = 'git+https://github.com/cytoscape/py4cytoscape@0.0.11'
import requests
exec(requests.get("https://raw.githubusercontent.com/cytoscape/jupyter-bridge/master/client/p4c_init.py").text)
IPython.display.Javascript(_PY4CYTOSCAPE_BROWSER_CLIENT_JS) # Start browser client

Note that to use the current py4cytoscape release (instead of v0.0.11), remove the _PY4CYTOSCAPE= line in the snippet above.

Sanity test to verify Cytoscape connection

By now, the connection to Cytoscape should be up and available. To verify this, try a simple operation that doesn’t alter the state of Cytoscape.

[1]:
import py4cytoscape as p4c
p4c.cytoscape_ping()
p4c.cytoscape_version_info()
You are connected to Cytoscape!
[1]:
{'apiVersion': 'v1',
 'cytoscapeVersion': '3.8.2',
 'automationAPIVersion': '1.2.0',
 'py4cytoscapeVersion': '0.0.11'}

Open Sample

For this tutorial, we will be using the galFiltered sample session file, which includes a yeast network and associated data.

[2]:
p4c.open_session()
Opening sampleData/sessions/Yeast Perturbation.cys...
[2]:
{}
[3]:
p4c.notebook_export_show_image()
[3]:
../_images/tutorials_Custom-Graphics_6_0.png

Set style and node color

First, lets change the style to a simple default and the color of nodes to grey:

[4]:
p4c.set_visual_style('default')
p4c.set_node_color_default('#D8D8D8')
style_name not specified, so updating "default" style.
[4]:
''
[5]:
p4c.notebook_export_show_image()
[5]:
../_images/tutorials_Custom-Graphics_9_0.png

Custom Graphics

Bar chart

In this example, we will create a bar chart with the three expression values, gal1RGexp, gal4RGexp and gal80Rexp, available as attributes in the session file.

Create the Custom Graphic:

[6]:
p4c.set_node_custom_bar_chart(["gal1RGexp","gal4RGexp","gal80Rexp"])
style_name not specified, so updating "default" style.
[6]:
''
[7]:
p4c.notebook_export_show_image()
[7]:
../_images/tutorials_Custom-Graphics_12_0.png

There are 4 types of Bar Charts and customizable parameters for colors, size, spacing and orientation.

Position the Bar Chart just below the node. This is an optional step that we are doing here just to make room for subsequent graphics. By specifying both anchors at opposite ends, we can get a lot of space between the node and the graphic.

[8]:
p4c.set_node_custom_position(node_anchor="S", graphic_anchor="N")
style_name not specified, so updating "default" style.
[8]:
''
[9]:
p4c.notebook_export_show_image()
[9]:
../_images/tutorials_Custom-Graphics_15_0.png

Stripes

Next we are going to create stripes of gradient mappings using a horizontal “heatmap”” of the same three data columns and position the heatmap right above the node. For this vignette, we need to also specify the slot number to avoid overwriting the Bar Chart:

[10]:
p4c.set_node_custom_heat_map_chart(["gal1RGexp","gal4RGexp","gal80Rexp"], slot=2)
p4c.set_node_custom_position(node_anchor="N", graphic_anchor="S", slot=2)
style_name not specified, so updating "default" style.
style_name not specified, so updating "default" style.
[10]:
''
[11]:
p4c.notebook_export_show_image()
[11]:
../_images/tutorials_Custom-Graphics_18_0.png

Pie chart

Finally, we will create a pie chart with two columns, Radiality and Degree, and place it to the left of the node. Here we’ll use the xOffset parameter to be even more specific about where we want to place the graphic relative to the node.

[12]:
p4c.set_node_custom_pie_chart(["Radiality", "Degree"], slot=3)
p4c.set_node_custom_position(node_anchor="W", x_offset=-20, slot=3)
style_name not specified, so updating "default" style.
style_name not specified, so updating "default" style.
[12]:
''
[13]:
p4c.notebook_export_show_image()
[13]:
../_images/tutorials_Custom-Graphics_21_0.png

Enhanced Graphics

The nodes in the network are labeled with the corresponding protein names (yeast), but there is additional text information in the Node Table that could be useful to display as labels on the nodes. We are going to use the enhancedGraphics app to create a second node label for the common yeast gene name.

This involves a new step: Filling a new column with parameters for the enhancedGraphics App. This column is then mapped to a Custom Graphic slot and (optionally) positioned, like in the examples above.

Install enhancedGraphics

The enhancedGraphics app is available from the Cytoscape App Store. In Cytoscape 3.8 and above, you can install apps from R with the following function:

[14]:
p4c.install_app("enhancedGraphics")
{}
[14]:
{}

Define new label

The new column values have to follow a specific syntax to be recognized by the enhancedGraphics app. Here, for example, is how you set a label based on another attribute (e.g., the column called “COMMON”), specifying its size, color, outline and background:

"label: attribute=COMMON labelsize=10 color=red outline=false background=false""

For more details on the enhancedGraphics format, `see the manual <http://www.cgl.ucsf.edu/cytoscape/utilities3/enhancedcg.shtml>`__.

First, we define a dataframe with two columns: node names (“name”) and the new label (“my second label”):

[15]:
import pandas as pd
all_nodes = p4c.get_all_nodes()
[16]:
label_df = pd.DataFrame([all_nodes, ["label: attribute=COMMON labelsize=10 color=red outline=false background=false"] * len(all_nodes)]).transpose()
[17]:
label_df.columns = ["name","my second label"]
[18]:
label_df
[18]:
name my second label
0 YDL194W label: attribute=COMMON labelsize=10 color=red...
1 YDR277C label: attribute=COMMON labelsize=10 color=red...
2 YBR043C label: attribute=COMMON labelsize=10 color=red...
3 YPR145W label: attribute=COMMON labelsize=10 color=red...
4 YER054C label: attribute=COMMON labelsize=10 color=red...
... ... ...
325 YOR204W label: attribute=COMMON labelsize=10 color=red...
326 YGL097W label: attribute=COMMON labelsize=10 color=red...
327 YGR218W label: attribute=COMMON labelsize=10 color=red...
328 YGL122C label: attribute=COMMON labelsize=10 color=red...
329 YKR026C label: attribute=COMMON labelsize=10 color=red...

330 rows × 2 columns

[19]:
p4c.get_table_columns()
[19]:
SUID shared name name selected AverageShortestPathLength BetweennessCentrality ClosenessCentrality ClusteringCoefficient Degree Eccentricity ... TopologicalCoefficient degree.layout COMMON gal1RGexp gal4RGexp gal80Rexp gal1RGsig gal4RGsig gal80Rsig isExcludedFromPaths
61 61 YDL194W YDL194W False 13.116935 0.0 0.076237 0.0 1 26 ... 0.0 1 SNF3 0.139 0.333 0.449 0.018043 0.033961 0.011348 False
62 62 YDR277C YDR277C False 12.120968 0.008065 0.082502 0.0 2 25 ... 0.5 2 MTH1 0.243 0.192 0.448 0.000022 0.028044 0.000573 False
63 63 YBR043C YBR043C False 1.5 0.0 0.666667 0.0 1 2 ... 0.0 1 YBR043C 0.454 0.023 0.0 0.0 0.94178 0.999999 False
64 64 YPR145W YPR145W False 9.798387 0.0 0.102058 0.0 1 18 ... 0.0 1 ASN1 -0.195 -0.614 -0.232 0.000032 0.0 0.001187 False
65 65 YER054C YER054C False 8.818548 0.044273 0.113397 0.0 2 19 ... 0.583333 2 GIP2 0.057 0.206 0.247 0.16958 0.00062 0.00436 False
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
386 386 YOR204W YOR204W False 1.666667 0.0 0.6 0.0 1 2 ... 0.0 1 DED1 -0.033 -0.056 -0.91 0.39944 0.31268 0.0 False
387 387 YGL097W YGL097W False 1.0 1.0 1.0 0.0 3 1 ... 0.0 3 SRM1 0.16 -0.23 0.008 0.002191 0.002246 0.93826 False
388 388 YGR218W YGR218W False 1.666667 0.0 0.6 0.0 1 2 ... 0.0 1 CRM1 -0.018 -0.001 -0.018 0.61381 0.9794 0.80969 False
389 389 YGL122C YGL122C False 14.375 0.024063 0.069565 0.0 3 25 ... 0.333333 3 NAB2 0.174 0.02 0.187 0.000873 0.61707 0.005997 False
390 390 YKR026C YKR026C False 15.370968 0.0 0.065058 0.0 1 26 ... 0.0 1 GCN3 -0.154 -0.501 0.292 0.000912 0.000004 0.011229 False

330 rows × 28 columns

Next, we load this dataframe into the Node Table to create and fill a new column:

[20]:
p4c.load_table_data(label_df, data_key_column="name", table_key_column="name")
[20]:
'Success: Data loaded in defaultnode table'
[21]:
p4c.get_table_columns()
[21]:
SUID shared name name selected AverageShortestPathLength BetweennessCentrality ClosenessCentrality ClusteringCoefficient Degree Eccentricity ... degree.layout COMMON gal1RGexp gal4RGexp gal80Rexp gal1RGsig gal4RGsig gal80Rsig isExcludedFromPaths my second label
61 61 YDL194W YDL194W False 13.116935 0.0 0.076237 0.0 1 26 ... 1 SNF3 0.139 0.333 0.449 0.018043 0.033961 0.011348 False label: attribute=COMMON labelsize=10 color=red...
62 62 YDR277C YDR277C False 12.120968 0.008065 0.082502 0.0 2 25 ... 2 MTH1 0.243 0.192 0.448 0.000022 0.028044 0.000573 False label: attribute=COMMON labelsize=10 color=red...
63 63 YBR043C YBR043C False 1.5 0.0 0.666667 0.0 1 2 ... 1 YBR043C 0.454 0.023 0.0 0.0 0.94178 0.999999 False label: attribute=COMMON labelsize=10 color=red...
64 64 YPR145W YPR145W False 9.798387 0.0 0.102058 0.0 1 18 ... 1 ASN1 -0.195 -0.614 -0.232 0.000032 0.0 0.001187 False label: attribute=COMMON labelsize=10 color=red...
65 65 YER054C YER054C False 8.818548 0.044273 0.113397 0.0 2 19 ... 2 GIP2 0.057 0.206 0.247 0.16958 0.00062 0.00436 False label: attribute=COMMON labelsize=10 color=red...
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
386 386 YOR204W YOR204W False 1.666667 0.0 0.6 0.0 1 2 ... 1 DED1 -0.033 -0.056 -0.91 0.39944 0.31268 0.0 False label: attribute=COMMON labelsize=10 color=red...
387 387 YGL097W YGL097W False 1.0 1.0 1.0 0.0 3 1 ... 3 SRM1 0.16 -0.23 0.008 0.002191 0.002246 0.93826 False label: attribute=COMMON labelsize=10 color=red...
388 388 YGR218W YGR218W False 1.666667 0.0 0.6 0.0 1 2 ... 1 CRM1 -0.018 -0.001 -0.018 0.61381 0.9794 0.80969 False label: attribute=COMMON labelsize=10 color=red...
389 389 YGL122C YGL122C False 14.375 0.024063 0.069565 0.0 3 25 ... 3 NAB2 0.174 0.02 0.187 0.000873 0.61707 0.005997 False label: attribute=COMMON labelsize=10 color=red...
390 390 YKR026C YKR026C False 15.370968 0.0 0.065058 0.0 1 26 ... 1 GCN3 -0.154 -0.501 0.292 0.000912 0.000004 0.011229 False label: attribute=COMMON labelsize=10 color=red...

330 rows × 29 columns

Map and position label

We now have a new column, my second label, that we can use for the mapping. This mapping does not come with a custom helper function, se we are going to use two alternative functions to prepare the passthrough mapping property and then update our visual style with the new mapping:

[22]:
label_map = p4c.map_visual_property('node customgraphics 4', 'my second label', 'p')
p4c.update_style_mapping('default', label_map)
[22]:
''
[23]:
p4c.notebook_export_show_image()
[23]:
../_images/tutorials_Custom-Graphics_35_0.png

Note: the custom graphic slot number is actulally part of the property’s name.

Finally, we position the new label in the upper right corner:

[24]:
p4c.set_node_custom_position(node_anchor="E", graphic_anchor="C", x_offset=10, slot=4)
style_name not specified, so updating "default" style.
[24]:
''
[25]:
p4c.notebook_export_show_image()
[25]:
../_images/tutorials_Custom-Graphics_38_0.png
[ ]: