8.6. Plotting Installation:

The plotting package allows you to make an interactive CRN plot. Plotting requires the Bokeh and ForceAtlas2 libraries to be installed on your machine. Bokeh is used for plotting, ForceAtlas2 is used for graph layout. To install, type the following into the consol:

conda install bokeh
pip install fa2_modified

Alternatively, follow the installation instructions in the links above.

Plotting Example

The CRN plot has a default representation:

  • species are circles

    • orange circles are RNA species

    • blue circles are complexes

    • green circles are proteins

    • grey circles are DNA -there’s always a purple circle that represents nothing. If your CRN doesn’t have reactions that go to nothing, then it won’t have any connections.

  • reactions are squares

Click on a node (either reaction or species) and all arrows including that node will be highlighted Mouse over a node (either reaction or species) and a tooltip will tell you what it is.

Create a BioCRNpyler Model

Here we model a DNA assembly with a regulated promoter in a TxTl mixture.

[1]:
from biocrnpyler.core import Species, Reaction
from biocrnpyler.components import DNAassembly, RegulatedPromoter
from biocrnpyler.mixtures import TxTlExtract


txtl = TxTlExtract("mixture1", parameter_file = 'default_parameters.txt')
dna = DNAassembly("mydna",promoter=RegulatedPromoter("plac",["laci"]),rbs="UTR1",protein="GFP", initial_concentration = 10)
txtl.add_component(dna)
crn1 = txtl.compile_crn()
crn1.add_reactions([Reaction.from_massaction([Species("mydna",material_type="rna")],[],k_forward=0.1)])
print(crn1.pretty_print())
/Users/murray/Library/CloudStorage/Dropbox/macosx/src/biocrnpyler/biocrnpyler/core/parameter.py:678: UserWarning: parameter file contains no unit column! Please add a column named ['unit', 'units'].
  warn(
Species(N = 13) = {
    rna[mydna] (@ 10),
    found_key=(mech=initial concentration, partid=None, name=mydna).
    search_key=(mech=initial concentration, partid=mixture1, name=mydna).

    dna[mydna] (@ 10),
    found_key=(mech=initial concentration, partid=None, name=mydna).
    search_key=(mech=initial concentration, partid=mixture1, name=mydna).

    complex[protein[Ribo]:rna[mydna]] (@ 0),
    complex[protein[RNAase]:rna[mydna]] (@ 0),
    protein[laci] (@ 0),
    complex[dna[mydna]:2x_protein[laci]] (@ 0),
    complex[dna[mydna]:protein[RNAP]] (@ 0),
    complex[complex[protein[Ribo]:rna[mydna]]:protein[RNAase]] (@ 0),
    complex[complex[dna[mydna]:2x_protein[laci]]:protein[RNAP]] (@ 0),
    protein[Ribo] (@ 0),
    protein[RNAase] (@ 0),
    protein[RNAP] (@ 0),
    protein[GFP] (@ 0),
}

Reactions (12) = [
0. dna[mydna]+protein[RNAP] <--> complex[dna[mydna]:protein[RNAP]]
 Kf=k_forward * dna_mydna * protein_RNAP
 Kr=k_reverse * complex_dna_mydna_protein_RNAP_
  k_forward=100.0
  found_key=(mech=None, partid=None, name=kb).
  search_key=(mech=transcription_mm, partid=plac_leak, name=kb).
  k_reverse=10.0
  found_key=(mech=None, partid=None, name=ku).
  search_key=(mech=transcription_mm, partid=plac_leak, name=ku).

1. complex[dna[mydna]:protein[RNAP]] --> dna[mydna]+rna[mydna]+protein[RNAP]
 Kf=k_forward * complex_dna_mydna_protein_RNAP_
  k_forward=0.05
  found_key=(mech=None, partid=None, name=ktx).
  search_key=(mech=transcription_mm, partid=plac_leak, name=ktx).

2. 2protein[laci]+dna[mydna] <--> complex[dna[mydna]:2x_protein[laci]]
 Kf=k_forward * protein_laci^2 * dna_mydna
 Kr=k_reverse * complex_dna_mydna_protein_laci_2x_
  k_forward=100.0
  found_key=(mech=None, partid=None, name=kb).
  search_key=(mech=one_step_cooperative_binding, partid=plac_laci, name=kb).
  k_reverse=10.0
  found_key=(mech=None, partid=None, name=ku).
  search_key=(mech=one_step_cooperative_binding, partid=plac_laci, name=ku).

3. complex[dna[mydna]:2x_protein[laci]]+protein[RNAP] <--> complex[complex[dna[mydna]:2x_protein[laci]]:protein[RNAP]]
 Kf=k_forward * complex_dna_mydna_protein_laci_2x_ * protein_RNAP
 Kr=k_reverse * complex_complex_dna_mydna_protein_laci_2x__protein_RNAP_
  k_forward=100.0
  found_key=(mech=None, partid=None, name=kb).
  search_key=(mech=transcription_mm, partid=plac_laci, name=kb).
  k_reverse=10.0
  found_key=(mech=None, partid=None, name=ku).
  search_key=(mech=transcription_mm, partid=plac_laci, name=ku).

4. complex[complex[dna[mydna]:2x_protein[laci]]:protein[RNAP]] --> complex[dna[mydna]:2x_protein[laci]]+rna[mydna]+protein[RNAP]
 Kf=k_forward * complex_complex_dna_mydna_protein_laci_2x__protein_RNAP_
  k_forward=0.05
  found_key=(mech=None, partid=None, name=ktx).
  search_key=(mech=transcription_mm, partid=plac_laci, name=ktx).

5. rna[mydna]+protein[Ribo] <--> complex[protein[Ribo]:rna[mydna]]
 Kf=k_forward * rna_mydna * protein_Ribo
 Kr=k_reverse * complex_protein_Ribo_rna_mydna_
  k_forward=100.0
  found_key=(mech=None, partid=None, name=kb).
  search_key=(mech=translation_mm, partid=UTR1, name=kb).
  k_reverse=10.0
  found_key=(mech=None, partid=None, name=ku).
  search_key=(mech=translation_mm, partid=UTR1, name=ku).

6. complex[protein[Ribo]:rna[mydna]] --> rna[mydna]+protein[GFP]+protein[Ribo]
 Kf=k_forward * complex_protein_Ribo_rna_mydna_
  k_forward=0.05
  found_key=(mech=None, partid=None, name=ktl).
  search_key=(mech=translation_mm, partid=UTR1, name=ktl).

7. complex[protein[Ribo]:rna[mydna]]+protein[RNAase] <--> complex[complex[protein[Ribo]:rna[mydna]]:protein[RNAase]]
 Kf=k_forward * complex_protein_Ribo_rna_mydna_ * protein_RNAase
 Kr=k_reverse * complex_complex_protein_Ribo_rna_mydna__protein_RNAase_
  k_forward=100.0
  found_key=(mech=None, partid=None, name=kb).
  search_key=(mech=rna_degradation_mm, partid=complex_protein_Ribo_rna_mydna_, name=kb).
  k_reverse=10.0
  found_key=(mech=None, partid=None, name=ku).
  search_key=(mech=rna_degradation_mm, partid=complex_protein_Ribo_rna_mydna_, name=ku).

8. complex[complex[protein[Ribo]:rna[mydna]]:protein[RNAase]] --> protein[Ribo]+protein[RNAase]
 Kf=k_forward * complex_complex_protein_Ribo_rna_mydna__protein_RNAase_
  k_forward=0.001
  found_key=(mech=rna_degradation_mm, partid=None, name=kdeg).
  search_key=(mech=rna_degradation_mm, partid=complex_protein_Ribo_rna_mydna_, name=kdeg).

9. rna[mydna]+protein[RNAase] <--> complex[protein[RNAase]:rna[mydna]]
 Kf=k_forward * rna_mydna * protein_RNAase
 Kr=k_reverse * complex_protein_RNAase_rna_mydna_
  k_forward=100.0
  found_key=(mech=None, partid=None, name=kb).
  search_key=(mech=rna_degradation_mm, partid=rna_mydna, name=kb).
  k_reverse=10.0
  found_key=(mech=None, partid=None, name=ku).
  search_key=(mech=rna_degradation_mm, partid=rna_mydna, name=ku).

10. complex[protein[RNAase]:rna[mydna]] --> protein[RNAase]
 Kf=k_forward * complex_protein_RNAase_rna_mydna_
  k_forward=0.001
  found_key=(mech=rna_degradation_mm, partid=None, name=kdeg).
  search_key=(mech=rna_degradation_mm, partid=rna_mydna, name=kdeg).

11. rna[mydna] -->
 Kf=k_forward * rna_mydna
  k_forward=0.1

]

Plotting a reaction graph

First we import bokeh in order to plot an interactive graph then use the graphPlot function and the BioCRNpyler.plotting.generate_networkx_graph(crn) function to produce a graph. Mouseover the circles to see which species they identify and the squares to see reactions.

[2]:
from biocrnpyler.utils.plotting import render_network_bokeh
try:
    from bokeh.models import (Plot , Range1d)
    import bokeh.plotting
    import bokeh.io
    bokeh.io.output_notebook() #this makes the graph appear in line with the notebook
    plot = render_network_bokeh(crn1)
    bokeh.io.show(plot) #if you don't type this the plot won't show
except ModuleNotFoundError:
    print('please install the plotting libraries: pip install biocrnpyler[all]')


#mouse over nodes to get a tooltip telling you what they are
#mouse over single lines to outline them
#click on nodes to highlight all edges that touch them
#use the magnifying glass symbol to zoom in and out
#click and drag to move around

#NOTE: this function is not deterministic in how it displays the network,
# because it uses randomness to push the nodes around. However, it does always get the same seed
# so if you don't change the network it will end up always looking the same. To set the seed use rseed=<some number>
Loading BokehJS ...
/Users/murray/Library/CloudStorage/Dropbox/macosx/src/biocrnpyler/biocrnpyler/utils/plotting.py:203: UserWarning: Node keys in 'layout_function' don't match node keys in the graph. These nodes may not be displayed correctly.
  reaction_renderer = from_networkx(DGreactions, positions, center=(0, 0))
/Users/murray/Library/CloudStorage/Dropbox/macosx/src/biocrnpyler/biocrnpyler/utils/plotting.py:204: UserWarning: Node keys in 'layout_function' don't match node keys in the graph. These nodes may not be displayed correctly.
  species_renderer = from_networkx(DGspecies, positions, center=(0, 0))

Advanced options for generate_networkx_graph

The following options are useful changing how plotting works.

To get better control over the way reactions and species text is display using the following keywords (default values shown below):

use_pretty_print=False
pp_show_rates=True
pp_show_attributes=True
pp_show_material=True

To get better control over the colors of different nodes, use the keywords to set a species’ color. The higher keywords will take precedence.

repr(species): "color"
species.name: "color"
(species.material_type, tuple(specie.attributes)): "color"
species.material_type: "color"
tuple(species.attributes): "color"
[3]:
try:
    from bokeh.models import (Plot , Range1d)
    import bokeh.plotting
    import bokeh.io
    bokeh.io.output_notebook() #this makes the graph appear in line with the notebook

    #this demonstrates the "circle" layout. reactions are in the middle with species on the outside.
    #also, the pretty_print text display style

    colordict = {
        "G1":"red", #will only effect the species dna_G1 and rna_G1
        "protein_GFP": "lightgreen", #will only effect the species protein_GFP
        "protein": "blue", #All protein species, protein_Ribo, protein_RNAase, and protein_RNAP will be blue
        #All other species will be grey by default. This will include all complexes.
    }

    plot = render_network_bokeh(crn1,
                            colordict = colordict,
                            use_pretty_print=True, #uses pretty print
                            pp_show_rates=False, #this would put the reaction rates in the reaction name. It's already listed seperately in the tool tip
                            pp_show_attributes=False,
                            pp_show_material = True, #this lists the material of the species being displayed
                            layout="circle",
    )
    bokeh.io.show(plot)
except ModuleNotFoundError:
    print('please install the plotting libraries: pip install biocrnpyler[all]')

Loading BokehJS ...
[4]:
from biocrnpyler.components import RBS, CDS, Terminator, DNA_construct
from biocrnpyler.utils.plotting import render_mixture, render_network_bokeh
#this is an example of how to use the new image plotting. It is designed to combine dnaplotlib and the network representation to show constructs and where proteins are bound to them.

#to use this to its full potential you must make dna_constructs:
txtl = TxTlExtract("mixture1", parameter_file = 'default_parameters.txt')

ptet = RegulatedPromoter("ptet",["tetR"])
utr1 = RBS("utr1")
gfp = CDS("GFP")
t16 = Terminator("t16")

construct = DNA_construct([ptet,utr1,gfp,t16], initial_concentration=5)


dna = DNAassembly("mydna",promoter=RegulatedPromoter("plac",["laci"]),rbs=utr1,protein="GFP", initial_concentration = 10)
txtl.add_component(dna)
txtl.add_component(construct)
crn1 = txtl.compile_crn()
crn1.add_reactions([Reaction.from_massaction([Species("mydna",material_type="rna")],[],k_forward=0.1)])
try:
    #dnaplotlib is a cool library for plotting DNAs.
    #please use my fork located at https://github.com/dr3y/dnaplotlib
    #to install it type: pip install git+git://github.com/dr3y/dnaplotlib.git@master
    import dnaplotlib as dpl # type: ignore
    %matplotlib inline
    dpl_enabled = True
except (ModuleNotFoundError,ImportError) as e:
    dpl_enabled = False

try:
    from bokeh.models import (Plot , Range1d)
    import bokeh.plotting
    import bokeh.io
    bokeh.io.output_notebook() #this makes the graph appear in line with the notebook

    #this demonstrates the "circle" layout. reactions are in the middle with species on the outside.
    #also, the pretty_print text display style

    colordict = {
        "G1":"red", #will only effect the species dna_G1 and rna_G1
        "protein_GFP": "green", #will only effect the species protein_GFP
        "GFP":"lightgreen", #this will affect how the dnaplotlib is drawn
        "protein": "blue", #All protein species, protein_Ribo, protein_RNAase, and protein_RNAP will be blue
        "transcription_mm":"green"
        #All other species will be grey by default. This will include all complexes.
    }
    reactioncolordict = {
        "kint":"yellow", #reactions containing "kint" will be yellow
        "kb":"cornflowerblue", #reactions containing "kb" will be cornflowerblue
        "ktx":"orange" #transcription reactions will be orange
        #all other reactions will be grey by default
        }
    if(dpl_enabled):
        images =render_mixture(txtl,crn1,colordict)
    else:
        images = None
    plot = render_network_bokeh(crn1,
                                                colordict = colordict,
                                                reactioncolordict = reactioncolordict,
                                                use_pretty_print=True, #uses pretty print
                                                pp_show_rates=False, #this would put the reaction rates in the reaction name. It's already listed seperately in the tool tip
                                                pp_show_attributes=False,
                                                pp_show_material = True, #this lists the material of the species being displayed
                                                imagedict =images, #this is a dictionary of which images to show for each species
                                                layout="circle",
    )
    bokeh.io.show(plot)
except ModuleNotFoundError:
    print('please install the plotting libraries: pip install biocrnpyler[all]')
/Users/murray/Library/CloudStorage/Dropbox/macosx/src/biocrnpyler/biocrnpyler/core/parameter.py:678: UserWarning: parameter file contains no unit column! Please add a column named ['unit', 'units'].
  warn(
Loading BokehJS ...
/Users/murray/Library/CloudStorage/Dropbox/macosx/src/biocrnpyler/biocrnpyler/utils/plotting.py:203: UserWarning: Node keys in 'layout_function' don't match node keys in the graph. These nodes may not be displayed correctly.
  reaction_renderer = from_networkx(DGreactions, positions, center=(0, 0))
/Users/murray/Library/CloudStorage/Dropbox/macosx/src/biocrnpyler/biocrnpyler/utils/plotting.py:204: UserWarning: Node keys in 'layout_function' don't match node keys in the graph. These nodes may not be displayed correctly.
  species_renderer = from_networkx(DGspecies, positions, center=(0, 0))
[5]:
# End