diff --git a/.gitignore b/.gitignore
index fd93017..3fe8076 100644
--- a/.gitignore
+++ b/.gitignore
@@ -58,3 +58,4 @@ docs/_build/
# PyBuilder
target/
+.vscode/settings.json
diff --git a/README.md b/README.md
index bce113e..47c94d7 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,5 @@
+pip install --upgrade --no-deps git+git://github.com/dr3y/dnaplotlib.git@master
+
# DNAplotlib
DNAplotlib is a library that enables highly customizable visualization of individual genetic constructs and libraries of design variants. It can be thought of in many ways as matplotlib for genetic diagrams. Publication quality vector-based output is produced and all aspects of the rendering process can be easily customized or replaced by the user. DNAplotlib is capable of SBOL Visual compliant diagrams in addition to a format able to better illustrate the precise location and length of each genetic part. This alternative "traced-based" visualization method enables direct comparison with nucleotide-level information such as RNA-seq read depth or other base resolution measures. While it is envisaged that access will be predominantly via the programming interface, several easy to use text-based input formats can be processed by a command-line scripts to facilitate broader usage. DNAplotlib is cross-platform and open-source software released under the OSI OSL-3.0 license.
@@ -12,8 +14,10 @@ The DNAplotlib library is contained within the `dnaplotlib.py` file in the `lib`
## Getting Started
We provide an extensive gallery of use cases for DNAplotlib in the `gallery` directory. Click on a thumbnail below to go directly to the example code:
+### Gallery of all part glyphs
+
+
### Genetic Designs and Annotation
-
diff --git a/dnaplotlib/dnaplotlib.py b/dnaplotlib/dnaplotlib.py
index ff6ab05..ec2edd1 100755
--- a/dnaplotlib/dnaplotlib.py
+++ b/dnaplotlib/dnaplotlib.py
@@ -4,21 +4,21 @@
==========
This module is designed to allow for highly customisable visualisation of DNA
fragments. Diagrams can be in the form of conceptual SBOL compliant icons or
- make use of icons whose width is scaled to allow for easier comparison of part
+ make use of icons whose width is scaled to allow for easier comparison of part
locations to trace information, such as for corresponding RNA-seq read depth
- data. All plotting is performed using matplotlib and to an axis object. This
+ data. All plotting is performed using matplotlib and to an axis object. This
enables the export of publication quality, vector-based figures. Furthermore,
- all standard renderers can be replaced with user defined versions to allow
+ all standard renderers can be replaced with user defined versions to allow
for full customisation of the plot.
- To make use of this module it is necessary to create the rendering object
+ To make use of this module it is necessary to create the rendering object
after importing the module:
> import dnaplotlib as dpl
> dr = dpl.DNARenderer()
This object performs all rendering using the renderDNA() method. To describe
- what should be plotted, dnaplotlib requires the DNA design in a specific
+ what should be plotted, dnaplotlib requires the DNA design in a specific
format. For standard SBOL diagrams a design is a list of dictionaries where
each dictionary relates to a specific part and as a minimum contains the
keys:
@@ -40,7 +40,7 @@
> start, end = dr.renderDNA(ax, design, part_renderers, regs, reg_renderers)
The function returns the start and end point of the design which can then
- be used for resizing the axes and figure. For more advanced use cases we
+ be used for resizing the axes and figure. For more advanced use cases we
advise looking at the gallery distributed with this module.
"""
@@ -52,11 +52,12 @@
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
-from matplotlib.patches import Polygon, Ellipse, Wedge, Circle, PathPatch
+from matplotlib.patches import Polygon, Ellipse, Wedge, Circle, PathPatch, FancyBboxPatch
from matplotlib.path import Path
from matplotlib.lines import Line2D
from matplotlib.patheffects import Stroke
import matplotlib.patches as patches
+import numpy as np
__author__ = 'Thomas E. Gorochowski \n\
@@ -100,7 +101,7 @@ def write_label (ax, label_text, x_pos, opts=None):
if 'label_rotation' in list(opts.keys()):
label_rotation = opts['label_rotation']
ax.text(x_pos+label_x_offset, label_y_offset+y_offset, label_text, horizontalalignment='center',
- verticalalignment='center', fontsize=label_size, fontstyle=label_style,
+ verticalalignment='center', fontsize=label_size, fontstyle=label_style,
color=label_color, rotation=label_rotation, zorder=30+zorder_add)
@@ -116,6 +117,7 @@ def sbol_promoter (ax, type, num, start, end, prev_end, scale, linewidth, opts):
x_extent = 10
arrowhead_height = 2
arrowhead_length = 4
+ y_offset = 0
# Reset defaults if provided
if opts != None:
if 'zorder_add' in list(opts.keys()):
@@ -138,6 +140,8 @@ def sbol_promoter (ax, type, num, start, end, prev_end, scale, linewidth, opts):
linewidth = opts['linewidth']
if 'scale' in list(opts.keys()):
scale = opts['scale']
+ if 'y_offset' in list(opts.keys()):
+ y_offset = opts['y_offset']
# Check direction add start padding
dir_fac = 1.0
final_end = end
@@ -152,18 +156,19 @@ def sbol_promoter (ax, type, num, start, end, prev_end, scale, linewidth, opts):
end = start+x_extent
final_end = end+end_pad
# Draw the promoter symbol
- l1 = Line2D([start,start],[0,dir_fac*y_extent], linewidth=linewidth,
+ l1 = Line2D([start,start],[0+y_offset,dir_fac*y_extent+y_offset], linewidth=linewidth,
color=color, zorder=9+zorder_add)
l2 = Line2D([start,start+dir_fac*x_extent-dir_fac*(arrowhead_length*0.5)],
- [dir_fac*y_extent,dir_fac*y_extent], linewidth=linewidth,
+ [dir_fac*y_extent+y_offset,dir_fac*y_extent+y_offset], linewidth=linewidth,
color=color, zorder=10+zorder_add)
ax.add_line(l1)
ax.add_line(l2)
- p1 = Polygon([(start+dir_fac*x_extent-dir_fac*arrowhead_length,
- dir_fac*y_extent+(arrowhead_height)),
- (start+dir_fac*x_extent, dir_fac*y_extent),
- (start+dir_fac*x_extent-dir_fac*arrowhead_length,
- dir_fac*y_extent-(arrowhead_height))],
+ p1 = Polygon([(start+dir_fac*x_extent-dir_fac*arrowhead_length,
+ dir_fac*y_extent+(arrowhead_height)+y_offset),
+ (start+dir_fac*x_extent,
+ dir_fac*y_extent+y_offset),
+ (start+dir_fac*x_extent-dir_fac*arrowhead_length,
+ dir_fac*y_extent+y_offset-(arrowhead_height))],
facecolor=color, edgecolor=color, linewidth=linewidth, zorder=1+zorder_add,
path_effects=[Stroke(joinstyle="miter")]) # This is a work around for matplotlib < 1.4.0
ax.add_patch(p1)
@@ -216,8 +221,8 @@ def sbol_cds (ax, type, num, start, end, prev_end, scale, linewidth, opts):
linewidth = opts['linewidth']
if 'scale' in list(opts.keys()):
scale = opts['scale']
- if 'edge_color' in list(opts.keys()):
- edgecolor = opts['edge_color']
+ if 'edgecolor' in list(opts.keys()):
+ edgecolor = opts['edgecolor']
# Check direction add start padding
dir_fac = 1.0
@@ -233,15 +238,15 @@ def sbol_cds (ax, type, num, start, end, prev_end, scale, linewidth, opts):
end = start+x_extent
final_end = end+end_pad
# Draw the CDS symbol
- p1 = Polygon([(start, y_extent),
+ p1 = Polygon([(start, y_extent),
(start, -y_extent),
(end-dir_fac*arrowhead_length, -y_extent),
(end-dir_fac*arrowhead_length, -y_extent-arrowhead_height),
(end, 0),
(end-dir_fac*arrowhead_length, y_extent+arrowhead_height),
(end-dir_fac*arrowhead_length, y_extent)],
- edgecolor=edgecolor, facecolor=color, linewidth=linewidth,
- hatch=hatch, zorder=11+zorder_add,
+ edgecolor=edgecolor, facecolor=color, linewidth=linewidth,
+ hatch=hatch, zorder=11+zorder_add,
path_effects=[Stroke(joinstyle="miter")]) # This is a work around for matplotlib < 1.4.0
ax.add_patch(p1)
if opts != None and 'label' in list(opts.keys()):
@@ -297,9 +302,9 @@ def sbol_terminator (ax, type, num, start, end, prev_end, scale, linewidth, opts
end = start+x_extent
final_end = end+end_pad
# Draw the terminator symbol
- l1 = Line2D([start+dir_fac*(x_extent/2.0),start+dir_fac*(x_extent/2.0)],[0,dir_fac*y_extent], linewidth=linewidth,
+ l1 = Line2D([start+dir_fac*(x_extent/2.0),start+dir_fac*(x_extent/2.0)],[0,dir_fac*y_extent], linewidth=linewidth,
color=color, zorder=8+zorder_add)
- l2 = Line2D([start,start+(dir_fac*x_extent)],[dir_fac*y_extent,dir_fac*y_extent],
+ l2 = Line2D([start,start+(dir_fac*x_extent)],[dir_fac*y_extent,dir_fac*y_extent],
linewidth=linewidth, color=color, zorder=9+zorder_add)
ax.add_line(l1)
ax.add_line(l2)
@@ -314,6 +319,113 @@ def sbol_terminator (ax, type, num, start, end, prev_end, scale, linewidth, opts
return prev_end, final_end
+def sbol_aptamer (ax, type, num, start, end, prev_end, scale, linewidth, opts):
+ """ Built-in SBOL terminator renderer.
+ """
+ # Default options
+ zorder_add = 0.0
+ color = (0,0,0)
+ start_pad = 0
+ end_pad = 0
+ y_extent = 12.0
+ x_extent = 12.0
+ # Reset defaults if provided
+ if opts != None:
+ if 'zorder_add' in list(opts.keys()):
+ zorder_add = opts['zorder_add']
+ if 'color' in list(opts.keys()):
+ color = opts['color']
+ if 'start_pad' in list(opts.keys()):
+ start_pad = opts['start_pad']
+ if 'end_pad' in list(opts.keys()):
+ end_pad = opts['end_pad']
+ if 'y_extent' in list(opts.keys()):
+ y_extent = opts['y_extent']
+ if 'x_extent' in list(opts.keys()):
+ x_extent = opts['x_extent']
+ if 'linewidth' in list(opts.keys()):
+ linewidth = opts['linewidth']
+ if 'scale' in list(opts.keys()):
+ scale = opts['scale']
+ # Check direction add start padding
+ dir_fac = 1.0
+ final_end = end
+ final_start = prev_end
+ if start > end:
+ dir_fac = -1.0
+ start = prev_end+end_pad
+ end = start+x_extent
+ final_end = end+start_pad
+ else:
+ start = prev_end+start_pad
+ end = start+x_extent
+ final_end = end+end_pad
+ # Draw the aptamer symbol
+ aptavertex = np.array([[ 0.43387125, -0.01575775],
+ [ 0.43387125, 0.27341225],
+ [ 0.51520025, 0.29435275],
+ [ 0.57536225, 0.3680035 ],
+ [ 0.57536225, 0.45586 ],
+ [ 0.57536225, 0.47506525],
+ [ 0.572457, 0.49357225],
+ [ 0.567137, 0.51102275],
+ [ 0.73824675, 0.60982125],
+ [ 0.751528, 0.60265225],
+ [ 0.7664885, 0.59823775],
+ [ 0.782656, 0.59823775],
+ [ 0.8347625, 0.59823775],
+ [ 0.8769835, 0.64045875],
+ [ 0.8769835, 0.69256525],
+ [ 0.8769835, 0.74465275],
+ [ 0.8347625, 0.7868925 ],
+ [ 0.782656, 0.7868925 ],
+ [ 0.73053075, 0.7868925 ],
+ [ 0.68832875, 0.74465275],
+ [ 0.68832875, 0.69256525],
+ [ 0.68832875, 0.69171525],
+ [ 0.68855375, 0.69090525],
+ [ 0.68859375, 0.69007525],
+ [ 0.5176915, 0.5914275 ],
+ [ 0.4837525, 0.6242535 ],
+ [ 0.4376265, 0.644515 ],
+ [ 0.386671, 0.644515 ],
+ [ 0.28251475, 0.644515 ],
+ [ 0.19801625, 0.56005425],
+ [ 0.19801625, 0.45586025],
+ [ 0.19801625, 0.367985 ],
+ [ 0.25817825, 0.294353 ],
+ [ 0.33950725, 0.2734125 ],
+ [ 0.33950725, -0.0157575 ]])
+ aptacodes = [1, 2, 4, 4, 4, 4,\
+ 4, 4, 2, 4, 4, 4,\
+ 4, 4, 4, 4, 4, 4,\
+ 4, 4, 4, 4, 4, 4,\
+ 2, 4, 4, 4, 4, 4,\
+ 4, 4, 4, 4, 2]
+ aptavertexFlip = np.dot(aptavertex,np.array([[-1,0],[0,-1]]))+(1,0)
+ aptavertexScaled = aptavertex*(x_extent,y_extent)+(start,0)
+ aptavertexFlipScaled = aptavertexFlip*(x_extent,y_extent)+(start,0)
+ #aptapath = Path(aptavertex,aptacodes)
+ #aptapathFlip = Path(aptavertexFlip,aptacodes)
+
+ if(dir_fac==-1):
+ aptapath = Path(aptavertexFlipScaled,aptacodes)
+ else:
+ aptapath = Path(aptavertexScaled,aptacodes)
+ aptapatch = PathPatch(aptapath, linewidth=linewidth, edgecolor=color,
+ facecolor=(1,1,1), zorder=8+zorder_add, linestyle='-')
+
+ ax.add_patch(aptapatch)
+ if opts != None and 'label' in list(opts.keys()):
+ if final_start > final_end:
+ write_label(ax, opts['label'], final_end+((final_start-final_end)/2.0), opts=opts)
+ else:
+ write_label(ax, opts['label'], final_start+((final_end-final_start)/2.0), opts=opts)
+ if final_start > final_end:
+ return prev_end, final_start
+ else:
+ return prev_end, final_end
+
def sbol_rbs (ax, type, num, start, end, prev_end, scale, linewidth, opts):
""" Built-in SBOL ribosome binding site renderer.
"""
@@ -340,8 +452,8 @@ def sbol_rbs (ax, type, num, start, end, prev_end, scale, linewidth, opts):
linewidth = opts['linewidth']
if 'scale' in list(opts.keys()):
scale = opts['scale']
- if 'edge_color' in list(opts.keys()):
- edgecolor = opts['edge_color']
+ if 'edgecolor' in list(opts.keys()):
+ edgecolor = opts['edgecolor']
# Check direction add start padding
dir_fac = 1.0
final_end = end
@@ -352,7 +464,7 @@ def sbol_rbs (ax, type, num, start, end, prev_end, scale, linewidth, opts):
end = prev_end+end_pad
final_end = start+start_pad
rbs_center = (end+((start-end)/2.0),0)
- w1 = Wedge(rbs_center, x_extent/2.0, 180, 360, linewidth=linewidth,
+ w1 = Wedge(rbs_center, x_extent/2.0, 180, 360, linewidth=linewidth,
facecolor=color, edgecolor=edgecolor, zorder=8+zorder_add)
ax.add_patch(w1)
else:
@@ -360,7 +472,7 @@ def sbol_rbs (ax, type, num, start, end, prev_end, scale, linewidth, opts):
end = start+x_extent
final_end = end+end_pad
rbs_center = (start+((end-start)/2.0),0)
- w1 = Wedge(rbs_center, x_extent/2.0, 0, 180, linewidth=linewidth,
+ w1 = Wedge(rbs_center, x_extent/2.0, 0, 180, linewidth=linewidth,
facecolor=color, edgecolor=edgecolor, zorder=8+zorder_add)
ax.add_patch(w1)
if opts != None and 'label' in list(opts.keys()):
@@ -391,8 +503,8 @@ def stick_figure (ax, type, num, start, end, prev_end, scale, linewidth, opts):
x_extent = 5.0
y_extent = 10.0
linestyle = '-'
- linetype = "";
- shapetype = "";
+ linetype = ""
+ shapetype = ""
if(type == "Ribozyme"):
linetype = 'dash'
headgroup = 'O'
@@ -435,20 +547,20 @@ def stick_figure (ax, type, num, start, end, prev_end, scale, linewidth, opts):
end = prev_end+end_pad
final_end = start+start_pad
rbs_center = (end+((start-end)/2.0),-y_extent)
- c1 = Circle(rbs_center, x_extent/2.0, linewidth=linewidth, edgecolor=color,
+ c1 = Circle(rbs_center, x_extent/2.0, linewidth=linewidth, edgecolor=color,
facecolor=(1,1,1), zorder=8+zorder_add)
- x1 = Line2D([start,end],[-y_extent*1.25,-y_extent/1.5],
+ x1 = Line2D([start,end],[-y_extent*1.25,-y_extent/1.5],
linewidth=linewidth, color=color, zorder=12+zorder_add, linestyle='-')
- x2 = Line2D([start,end],[-y_extent/1.5,-y_extent*1.25],
+ x2 = Line2D([start,end],[-y_extent/1.5,-y_extent*1.25],
linewidth=linewidth, color=color, zorder=12+zorder_add, linestyle='-')
- dash1 = Line2D([end+((start-end)/2.0),end+((start-end)/2.0)],[0,-y_extent/4],
+ dash1 = Line2D([end+((start-end)/2.0),end+((start-end)/2.0)],[0,-y_extent/4],
linewidth=linewidth, color=color, zorder=8+zorder_add, linestyle=linestyle)
- dash2 = Line2D([end+((start-end)/2.0),end+((start-end)/2.0)],[-y_extent/2,-y_extent+(x_extent/2.0)],
+ dash2 = Line2D([end+((start-end)/2.0),end+((start-end)/2.0)],[-y_extent/2,-y_extent+(x_extent/2.0)],
linewidth=linewidth, color=color, zorder=8+zorder_add, linestyle=linestyle)
- solidO = Line2D([end+((start-end)/2.0),end+((start-end)/2.0)],[0,-y_extent+(x_extent/2.0)],
+ solidO = Line2D([end+((start-end)/2.0),end+((start-end)/2.0)],[0,-y_extent+(x_extent/2.0)],
linewidth=linewidth, color=color, zorder=8+zorder_add, linestyle=linestyle)
- solidX = Line2D([end+((start-end)/2.0),end+((start-end)/2.0)],[0,-y_extent],
+ solidX = Line2D([end+((start-end)/2.0),end+((start-end)/2.0)],[0,-y_extent],
linewidth=linewidth, color=color, zorder=8+zorder_add, linestyle=linestyle)
if(headgroup == "O" and linetype == "dash"):
@@ -472,20 +584,20 @@ def stick_figure (ax, type, num, start, end, prev_end, scale, linewidth, opts):
end = start+x_extent
final_end = end+end_pad
rbs_center = (start+((end-start)/2.0),y_extent)
- c1 = Circle(rbs_center, x_extent/2.0, linewidth=linewidth, edgecolor=color,
+ c1 = Circle(rbs_center, x_extent/2.0, linewidth=linewidth, edgecolor=color,
facecolor=(1,1,1), zorder=8+zorder_add)
- x1 = Line2D([start,end],[y_extent*1.25,y_extent/1.5],
+ x1 = Line2D([start,end],[y_extent*1.25,y_extent/1.5],
linewidth=linewidth, color=color, zorder=12+zorder_add, linestyle='-')
- x2 = Line2D([start,end],[y_extent/1.5,y_extent*1.25],
+ x2 = Line2D([start,end],[y_extent/1.5,y_extent*1.25],
linewidth=linewidth, color=color, zorder=12+zorder_add, linestyle='-')
- dash1 = Line2D([end+((start-end)/2.0),end+((start-end)/2.0)],[0,y_extent/4],
+ dash1 = Line2D([end+((start-end)/2.0),end+((start-end)/2.0)],[0,y_extent/4],
linewidth=linewidth, color=color, zorder=8+zorder_add, linestyle=linestyle)
- dash2 = Line2D([end+((start-end)/2.0),end+((start-end)/2.0)],[y_extent/2,y_extent-(x_extent/2.0)],
+ dash2 = Line2D([end+((start-end)/2.0),end+((start-end)/2.0)],[y_extent/2,y_extent-(x_extent/2.0)],
linewidth=linewidth, color=color, zorder=8+zorder_add, linestyle=linestyle)
- solidO = Line2D([end+((start-end)/2.0),end+((start-end)/2.0)],[0,y_extent-(x_extent/2.0)],
+ solidO = Line2D([end+((start-end)/2.0),end+((start-end)/2.0)],[0,y_extent-(x_extent/2.0)],
linewidth=linewidth, color=color, zorder=8+zorder_add, linestyle=linestyle)
- solidX = Line2D([end+((start-end)/2.0),end+((start-end)/2.0)],[0,y_extent],
+ solidX = Line2D([end+((start-end)/2.0),end+((start-end)/2.0)],[0,y_extent],
linewidth=linewidth, color=color, zorder=8+zorder_add, linestyle=linestyle)
if(headgroup == 'O' and linetype == 'dash'):
@@ -504,7 +616,7 @@ def stick_figure (ax, type, num, start, end, prev_end, scale, linewidth, opts):
ax.add_line(x1)
ax.add_line(x2)
ax.add_line(solidX)
-
+
if opts != None and 'label' in list(opts.keys()):
if final_start > final_end:
write_label(ax, opts['label'], final_end+((final_start-final_end)/2.0), opts=opts)
@@ -834,17 +946,17 @@ def sbol_scar (ax, type, num, start, end, prev_end, scale, linewidth, opts):
start = prev_end+start_pad
end = start+x_extent
final_end = end+end_pad
-
- l_top = Line2D([start,start+x_extent],[y_extent,y_extent],
+
+ l_top = Line2D([start,start+x_extent],[y_extent,y_extent],
linewidth=linewidth, color=color, zorder=12+zorder_add, linestyle=linestyle)
- l_bottom = Line2D([start,start+x_extent],[-1*y_extent,-1*y_extent],
+ l_bottom = Line2D([start,start+x_extent],[-1*y_extent,-1*y_extent],
linewidth=linewidth, color=color, zorder=12+zorder_add, linestyle=linestyle)
#white rectangle overlays backbone line
- p1 = Polygon([(start, y_extent),
+ p1 = Polygon([(start, y_extent),
(start, -y_extent),
(start+x_extent, -y_extent),
(start+x_extent, y_extent)],
- edgecolor=(1,1,1), facecolor=(1,1,1), linewidth=linewidth, zorder=11+zorder_add,
+ edgecolor=(1,1,1), facecolor=(1,1,1), linewidth=linewidth, zorder=11+zorder_add,
path_effects=[Stroke(joinstyle="miter")]) # This is a work around for matplotlib < 1.4.0)
ax.add_patch(p1)
@@ -922,24 +1034,31 @@ def sbol_5_overhang (ax, type, num, start, end, prev_end, scale, linewidth, opts
if 'scale' in list(opts.keys()):
scale = opts['scale']
# Check direction add start padding
- final_end = end
+ fliptopbottom = 1
final_start = prev_end
+ spmod = 0
+ if(start > end):
+ start = prev_end+end_pad
+ end = start+x_extent
+ fliptopbottom = -1
+ final_end = end+start_pad
+ spmod = (x_extent/2.0)
+ else:
+ start = prev_end+start_pad
+ end = start+x_extent
+ final_end = end+end_pad
- start = prev_end+start_pad
- end = start+x_extent
- final_end = end+end_pad
-
- l_top = Line2D([start,start+x_extent],[y_extent,y_extent],
+ l_top = Line2D([start,start+x_extent],[y_extent*fliptopbottom,y_extent*fliptopbottom],
linewidth=linewidth, color=color, zorder=12+zorder_add, linestyle=linestyle)
- l_bottom = Line2D([start+(x_extent/2.0),start+x_extent],[-1*y_extent,-1*y_extent],
+ l_bottom = Line2D([start+(x_extent/2.0)-spmod,start+x_extent-spmod],[-1*y_extent*fliptopbottom,-1*y_extent*fliptopbottom],
linewidth=linewidth, color=color, zorder=12+zorder_add, linestyle=linestyle)
#white rectangle overlays backbone line
- p1 = Polygon([(start, y_extent),
+ p1 = Polygon([(start, y_extent),
(start, -y_extent),
(start+x_extent, -y_extent),
(start+x_extent, y_extent)],
- edgecolor=(1,1,1), facecolor=(1,1,1), linewidth=linewidth, zorder=11+zorder_add,
- path_effects=[Stroke(joinstyle="miter")]) # This is a work around for matplotlib < 1.4.0)
+ edgecolor=(1,1,1), facecolor=(1,1,1), linewidth=linewidth, zorder=11+zorder_add,
+ path_effects=[Stroke(joinstyle="miter")]) # This is a work around for matplotlib < 1.4.0)
ax.add_patch(p1)
ax.add_line(l_top)
@@ -989,24 +1108,31 @@ def sbol_3_overhang (ax, type, num, start, end, prev_end, scale, linewidth, opts
if 'scale' in list(opts.keys()):
scale = opts['scale']
# Check direction add start padding
- final_end = end
+ fliptopbottom = 1
final_start = prev_end
+ spmod = 0
+ if(start > end):
+ start = prev_end+end_pad
+ end = start+x_extent
+ fliptopbottom = -1
+ final_end = end+start_pad
+ spmod = (x_extent/2.0)
+ else:
+ start = prev_end+start_pad
+ end = start+x_extent
+ final_end = end+end_pad
- start = prev_end+start_pad
- end = start+x_extent
- final_end = end+end_pad
-
- l_top = Line2D([start,start+x_extent],[y_extent,y_extent],
+ l_top = Line2D([start,start+x_extent],[y_extent*fliptopbottom,y_extent*fliptopbottom],
linewidth=linewidth, color=color, zorder=12+zorder_add, linestyle=linestyle)
- l_bottom = Line2D([start,start+(x_extent/2.0)],[-1*y_extent,-1*y_extent],
+ l_bottom = Line2D([start+spmod,start+(x_extent/2.0)+spmod],[-1*y_extent*fliptopbottom,-1*y_extent*fliptopbottom],
linewidth=linewidth, color=color, zorder=12+zorder_add, linestyle=linestyle)
#white rectangle overlays backbone line
- p1 = Polygon([(start, y_extent),
+ p1 = Polygon([(start, y_extent),
(start, -y_extent),
(start+x_extent, -y_extent),
(start+x_extent, y_extent)],
- edgecolor=(1,1,1), facecolor=(1,1,1), linewidth=linewidth, zorder=11+zorder_add,
- path_effects=[Stroke(joinstyle="miter")]) # This is a work around for matplotlib < 1.4.0)
+ edgecolor=(1,1,1), facecolor=(1,1,1), linewidth=linewidth, zorder=11+zorder_add,
+ path_effects=[Stroke(joinstyle="miter")]) # This is a work around for matplotlib < 1.4.0)
ax.add_patch(p1)
ax.add_line(l_top)
@@ -1058,7 +1184,7 @@ def sbol_blunt_restriction_site (ax, type, num, start, end, prev_end, scale, lin
linewidth = opts['linewidth']
if 'scale' in list(opts.keys()):
scale = opts['scale']
-
+
# Direction is meaningless for this part => start is always < end
if start > end:
temp_end = end
@@ -1071,21 +1197,21 @@ def sbol_blunt_restriction_site (ax, type, num, start, end, prev_end, scale, lin
start = prev_end+start_pad
end = start+x_extent+site_space+x_extent
final_end = end+end_pad
-
- l1 = Line2D([start+x_extent,start+x_extent],[-y_extent,y_extent],
+
+ l1 = Line2D([start+x_extent,start+x_extent],[-y_extent,y_extent],
linewidth=linewidth, color=color, zorder=12+zorder_add, linestyle=linestyle)
- l1_top = Line2D([start,start+x_extent],[y_extent,y_extent],
+ l1_top = Line2D([start,start+x_extent],[y_extent,y_extent],
linewidth=linewidth, color=color, zorder=12+zorder_add, linestyle=linestyle)
- l1_bottom = Line2D([start,start+x_extent],[-y_extent,-y_extent],
+ l1_bottom = Line2D([start,start+x_extent],[-y_extent,-y_extent],
linewidth=linewidth, color=color, zorder=12+zorder_add, linestyle=linestyle)
- l2 = Line2D([end-x_extent,end-x_extent],[-y_extent,y_extent],
+ l2 = Line2D([end-x_extent,end-x_extent],[-y_extent,y_extent],
linewidth=linewidth, color=color, zorder=12+zorder_add, linestyle=linestyle)
- l2_top = Line2D([end,end-x_extent],[y_extent,y_extent],
+ l2_top = Line2D([end,end-x_extent],[y_extent,y_extent],
linewidth=linewidth, color=color, zorder=12+zorder_add, linestyle=linestyle)
- l2_bottom = Line2D([end,end-x_extent],[-y_extent,-y_extent],
+ l2_bottom = Line2D([end,end-x_extent],[-y_extent,-y_extent],
linewidth=linewidth, color=color, zorder=12+zorder_add, linestyle=linestyle)
-
+
ax.add_line(l1)
ax.add_line(l1_top)
ax.add_line(l1_bottom)
@@ -1136,7 +1262,7 @@ def sbol_primer_binding_site (ax, type, num, start, end, prev_end, scale, linewi
linewidth = opts['linewidth']
if 'scale' in list(opts.keys()):
scale = opts['scale']
-
+
direction = 'F'
if start > end:
direction = 'R'
@@ -1217,7 +1343,7 @@ def sbol_5_sticky_restriction_site (ax, type, num, start, end, prev_end, scale,
linewidth = opts['linewidth']
if 'scale' in list(opts.keys()):
scale = opts['scale']
-
+
# Direction is meaningless for this part => start is always < end
if start > end:
temp_end = end
@@ -1230,24 +1356,24 @@ def sbol_5_sticky_restriction_site (ax, type, num, start, end, prev_end, scale,
start = prev_end+start_pad
end = start+end_space+x_extent+end_space
final_end = end+end_pad
-
- l1 = Line2D([start+end_space,start+end_space+x_extent],[0,0],
+
+ l1 = Line2D([start+end_space,start+end_space+x_extent],[0,0],
linewidth=linewidth, color=color, zorder=12+zorder_add, linestyle=linestyle)
- l1_top = Line2D([start+end_space,start+end_space],[0,y_extent],
+ l1_top = Line2D([start+end_space,start+end_space],[0,y_extent],
linewidth=linewidth, color=color, zorder=12+zorder_add, linestyle=linestyle)
- l1_bottom = Line2D([start+end_space+x_extent,start+end_space+x_extent],[0,-y_extent],
+ l1_bottom = Line2D([start+end_space+x_extent,start+end_space+x_extent],[0,-y_extent],
linewidth=linewidth, color=color, zorder=12+zorder_add, linestyle=linestyle)
ax.add_line(l1)
ax.add_line(l1_top)
ax.add_line(l1_bottom)
# White rectangle overlays backbone line
- p1 = Polygon([(start, y_extent),
+ p1 = Polygon([(start, y_extent),
(start, -y_extent),
(end, -y_extent),
(end, y_extent)],
- edgecolor=(1,1,1), facecolor=(1,1,1), linewidth=linewidth, zorder=11+zorder_add,
- path_effects=[Stroke(joinstyle="miter")]) # This is a work around for matplotlib < 1.4.0)
+ edgecolor=(1,1,1), facecolor=(1,1,1), linewidth=linewidth, zorder=11+zorder_add,
+ path_effects=[Stroke(joinstyle="miter")]) # This is a work around for matplotlib < 1.4.0)
ax.add_patch(p1)
@@ -1291,7 +1417,7 @@ def sbol_3_sticky_restriction_site (ax, type, num, start, end, prev_end, scale,
linewidth = opts['linewidth']
if 'scale' in list(opts.keys()):
scale = opts['scale']
-
+
# Direction is meaningless for this part => start is always < end
if start > end:
temp_end = end
@@ -1304,24 +1430,24 @@ def sbol_3_sticky_restriction_site (ax, type, num, start, end, prev_end, scale,
start = prev_end+start_pad
end = start+end_space+x_extent+end_space
final_end = end+end_pad
-
- l1 = Line2D([start+end_space,start+end_space+x_extent],[0,0],
+
+ l1 = Line2D([start+end_space,start+end_space+x_extent],[0,0],
linewidth=linewidth, color=color, zorder=12+zorder_add, linestyle=linestyle)
- l1_top = Line2D([start+end_space+x_extent,start+end_space+x_extent],[0,y_extent],
+ l1_top = Line2D([start+end_space+x_extent,start+end_space+x_extent],[0,y_extent],
linewidth=linewidth, color=color, zorder=12+zorder_add, linestyle=linestyle)
- l1_bottom = Line2D([start+end_space,start+end_space],[0,-y_extent],
+ l1_bottom = Line2D([start+end_space,start+end_space],[0,-y_extent],
linewidth=linewidth, color=color, zorder=12+zorder_add, linestyle=linestyle)
ax.add_line(l1)
ax.add_line(l1_top)
ax.add_line(l1_bottom)
# White rectangle overlays backbone line
- p1 = Polygon([(start, y_extent),
+ p1 = Polygon([(start, y_extent),
(start, -y_extent),
(end, -y_extent),
(end, y_extent)],
- edgecolor=(1,1,1), facecolor=(1,1,1), linewidth=linewidth, zorder=11+zorder_add,
- path_effects=[Stroke(joinstyle="miter")]) # This is a work around for matplotlib < 1.4.0)
+ edgecolor=(1,1,1), facecolor=(1,1,1), linewidth=linewidth, zorder=11+zorder_add,
+ path_effects=[Stroke(joinstyle="miter")]) # This is a work around for matplotlib < 1.4.0)
ax.add_patch(p1)
@@ -1372,17 +1498,17 @@ def sbol_user_defined (ax, type, num, start, end, prev_end, scale, linewidth, o
start = prev_end+start_pad
end = start+x_extent
final_end = end+end_pad
-
+
#white rectangle overlays backbone line
- p1 = Polygon([(start, y_extent),
+ p1 = Polygon([(start, y_extent),
(start, -y_extent),
(start+x_extent, -y_extent),
(start+x_extent, y_extent)],
- edgecolor=color, facecolor=fill_color, linewidth=linewidth, zorder=11+zorder_add,
- path_effects=[Stroke(joinstyle="miter")]) # This is a work around for matplotlib < 1.4.0)
+ edgecolor=color, facecolor=fill_color, linewidth=linewidth, zorder=11+zorder_add,
+ path_effects=[Stroke(joinstyle="miter")]) # This is a work around for matplotlib < 1.4.0)
ax.add_patch(p1)
-
+
if opts != None and 'label' in list(opts.keys()):
if final_start > final_end:
write_label(ax, opts['label'], final_end+((final_start-final_end)/2.0), opts=opts)
@@ -1429,7 +1555,7 @@ def sbol_signature (ax, type, num, start, end, prev_end, scale, linewidth, opts
linewidth = opts['linewidth']
if 'scale' in list(opts.keys()):
scale = opts['scale']
-
+
direction = 'F'
if start > end:
direction = 'R'
@@ -1455,12 +1581,12 @@ def sbol_signature (ax, type, num, start, end, prev_end, scale, linewidth, opts
cross_width = (y_extent*2.0)*0.7
if direction == 'F':
- p1 = Polygon([(start, y_extent),
+ p1 = Polygon([(start, y_extent),
(start, -y_extent),
(start+x_extent, -y_extent),
(start+x_extent, y_extent)],
- edgecolor=color, facecolor=fill_color, linewidth=linewidth, zorder=11+zorder_add,
- path_effects=[Stroke(joinstyle="miter")]) # This is a work around for matplotlib < 1.4.0)
+ edgecolor=color, facecolor=fill_color, linewidth=linewidth, zorder=11+zorder_add,
+ path_effects=[Stroke(joinstyle="miter")]) # This is a work around for matplotlib < 1.4.0)
ax.add_patch(p1)
top1x = start + indent_fac
top1y = y_extent - indent_fac
@@ -1470,21 +1596,21 @@ def sbol_signature (ax, type, num, start, end, prev_end, scale, linewidth, opts
bot1y = -y_extent + indent_fac
bot2x = start + cross_width
bot2y = -y_extent + indent_fac
- lcross1 = Line2D([top1x,bot2x],[top1y,bot2y],
+ lcross1 = Line2D([top1x,bot2x],[top1y,bot2y],
linewidth=linewidth, color=color, zorder=12+zorder_add, linestyle=linestyle)
- lcross2 = Line2D([top2x,bot1x],[top2y,bot1y],
+ lcross2 = Line2D([top2x,bot1x],[top2y,bot1y],
linewidth=linewidth, color=color, zorder=12+zorder_add, linestyle=linestyle)
ax.add_line(lcross1)
ax.add_line(lcross2)
- lsign = Line2D([bot2x+indent_fac,end-indent_fac],[-y_extent+indent_fac,-y_extent+indent_fac],
+ lsign = Line2D([bot2x+indent_fac,end-indent_fac],[-y_extent+indent_fac,-y_extent+indent_fac],
linewidth=linewidth, color=color, zorder=12+zorder_add, linestyle=linestyle)
ax.add_line(lsign)
else:
- p1 = Polygon([(start, y_extent),
+ p1 = Polygon([(start, y_extent),
(start, -y_extent),
(start-x_extent, -y_extent),
(start-x_extent, y_extent)],
- edgecolor=color, facecolor=fill_color, linewidth=linewidth, zorder=11+zorder_add,
+ edgecolor=color, facecolor=fill_color, linewidth=linewidth, zorder=11+zorder_add,
path_effects=[Stroke(joinstyle="miter")]) # This is a work around for matplotlib < 1.4.0)
ax.add_patch(p1)
top1x = start - indent_fac
@@ -1495,13 +1621,13 @@ def sbol_signature (ax, type, num, start, end, prev_end, scale, linewidth, opts
bot1y = -y_extent + indent_fac
bot2x = start - cross_width
bot2y = -y_extent + indent_fac
- lcross1 = Line2D([top1x,bot2x],[top1y,bot2y],
+ lcross1 = Line2D([top1x,bot2x],[top1y,bot2y],
linewidth=linewidth, color=color, zorder=12+zorder_add, linestyle=linestyle)
- lcross2 = Line2D([top2x,bot1x],[top2y,bot1y],
+ lcross2 = Line2D([top2x,bot1x],[top2y,bot1y],
linewidth=linewidth, color=color, zorder=12+zorder_add, linestyle=linestyle)
ax.add_line(lcross1)
ax.add_line(lcross2)
- lsign = Line2D([bot2x-indent_fac,end+indent_fac],[y_extent-indent_fac,y_extent-indent_fac],
+ lsign = Line2D([bot2x-indent_fac,end+indent_fac],[y_extent-indent_fac,y_extent-indent_fac],
linewidth=linewidth, color=color, zorder=12+zorder_add, linestyle=linestyle)
ax.add_line(lsign)
@@ -1515,6 +1641,262 @@ def sbol_signature (ax, type, num, start, end, prev_end, scale, linewidth, opts
return prev_end, final_start
else:
return prev_end, final_end
+def sbol_recombinase1 (ax, type, num, start, end, prev_end, scale, linewidth, opts):
+ """ SBOL recombinase site renderer - forward direction
+ """
+ # Default parameters
+ color = (0,0,0)
+ color2 = (0,0,0)
+ start_pad = 0.0
+ end_pad = 0.0
+ x_extent = 12.0
+ y_extent = 12.0
+ linestyle = '-'
+ edgecolor = (0,0,0)
+ # Update default parameters if provided
+ if opts != None:
+ if 'start_pad' in list(opts.keys()):
+ start_pad = opts['start_pad']
+ if 'end_pad' in list(opts.keys()):
+ end_pad = opts['end_pad']
+ if 'x_extent' in list(opts.keys()):
+ x_extent = opts['x_extent']
+ if 'y_extent' in list(opts.keys()):
+ y_extent = opts['y_extent']
+ if 'linestyle' in list(opts.keys()):
+ linestyle = opts['linestyle']
+ if 'linewidth' in list(opts.keys()):
+ linewidth = opts['linewidth']
+ if 'scale' in list(opts.keys()):
+ scale = opts['scale']
+ if 'color' in list(opts.keys()):
+ color = opts['color']
+ if 'color2' in list(opts.keys()):
+ color2 = opts['color2']
+ if 'edgecolor' in list(opts.keys()):
+ edgecolor = opts['edgecolor']
+ # Check direction add start padding
+ final_end = end
+ final_start = prev_end
+ y_lower = -1 * y_extent/2
+ y_upper = y_extent/2
+
+
+ if start > end:
+ start = prev_end+end_pad+x_extent+linewidth
+ end = prev_end+end_pad+linewidth
+ final_end = start+start_pad+linewidth
+ #temp = color
+ #color = color2
+ #color2 = temp
+ else:
+ start = prev_end+start_pad+linewidth
+ end = start+x_extent
+ final_end = end+end_pad+linewidth
+ # Draw the site
+ p1 = Polygon([(start, y_lower),
+ (start, y_upper),
+ (end,0)],
+ edgecolor=edgecolor, facecolor=color, linewidth=linewidth, zorder=11,
+ path_effects=[Stroke(joinstyle="miter")])
+ ax.add_patch(p1)
+ # Add a label if needed
+ if opts != None and 'label' in list(opts.keys()):
+ if final_start > final_end:
+ write_label(ax, opts['label'], final_end+((final_start-final_end)/2.0), opts=opts)
+ else:
+ write_label(ax, opts['label'], final_start+((final_end-final_start)/2.0), opts=opts)
+ # Return the final start and end positions to the DNA renderer
+ if final_start > final_end:
+ return prev_end, final_start
+ else:
+ return prev_end, final_end
+
+def sbol_ncrna (ax, type, num, start, end, prev_end, scale, linewidth, opts):
+ """ SBOL recombinase site renderer - reverse direction
+ """
+ # Default parameters
+ color = (0,0,0)
+ start_pad = 0.0
+ end_pad = 0.0
+ x_extent = 30.0
+ y_extent = 6.0
+ linestyle = '-'
+ edgecolor = (0,0,0)
+ # Update default parameters if provided
+ if opts != None:
+ if 'start_pad' in list(opts.keys()):
+ start_pad = opts['start_pad']
+ if 'end_pad' in list(opts.keys()):
+ end_pad = opts['end_pad']
+ if 'x_extent' in list(opts.keys()):
+ x_extent = opts['x_extent']
+ if 'y_extent' in list(opts.keys()):
+ y_extent = opts['y_extent']
+ if 'linestyle' in list(opts.keys()):
+ linestyle = opts['linestyle']
+ if 'linewidth' in list(opts.keys()):
+ linewidth = opts['linewidth']
+ if 'scale' in list(opts.keys()):
+ scale = opts['scale']
+ if 'color' in list(opts.keys()):
+ color = opts['color']
+ if 'edgecolor' in list(opts.keys()):
+ edgecolor = opts['edgecolor']
+ # Check direction add start padding
+
+ final_end = end
+ final_start = prev_end
+ y_lower = -1 * y_extent/2
+ y_upper = y_extent/2
+ wavemult = 1
+ #print("oogabooga")
+ if start > end:
+ start = prev_end+end_pad+x_extent+linewidth
+ end = prev_end+end_pad+linewidth
+ final_end = start+start_pad+linewidth
+ wavemult = -1
+ else:
+ start = prev_end+start_pad+linewidth
+ end = start+x_extent
+ final_end = end+end_pad+linewidth
+ midpoint = (end + start) / 2
+
+
+ wave_height = wavemult*y_extent
+ #wave_height = -y_extent
+ wave_start = start
+ wave_end = end
+ wave_length = end-start
+ wave_bezier_amp = y_extent*0.2
+ wave_bezier_dx = wave_length/15.0#wave_bezier_amp*math.cos(math.pi/4)
+ wave_bezier_dy = wavemult*wave_bezier_amp*math.sin(math.pi/4)
+ wavy_rna_path = Path(vertices=[[wave_start,0],
+ [wave_start, wave_height],
+ [wave_start + wave_bezier_dx, wave_height+wave_bezier_dy],
+ [wave_start + wave_bezier_dx*2, wave_height+wave_bezier_dy],
+ [wave_start + wave_bezier_dx*3, wave_height],
+ [wave_start + wave_bezier_dx*4, wave_height-wave_bezier_dy],
+ [wave_start + wave_bezier_dx*5, wave_height-wave_bezier_dy],
+ [wave_start + wave_bezier_dx*6, wave_height],
+ [wave_start + wave_bezier_dx*7, wave_height+wave_bezier_dy],
+ [wave_start + wave_bezier_dx*8, wave_height+wave_bezier_dy],
+ [wave_start + wave_bezier_dx*9, wave_height],
+ [wave_start + wave_bezier_dx*10, wave_height-wave_bezier_dy],
+ [wave_start + wave_bezier_dx*11, wave_height-wave_bezier_dy],
+ [wave_start + wave_bezier_dx*12, wave_height],
+ [wave_start + wave_bezier_dx*13, wave_height+wave_bezier_dy],
+ [wave_start + wave_bezier_dx*14, wave_height+wave_bezier_dy],
+ [wave_end,wave_height],
+ [wave_end,0],
+ [wave_end,0]
+ ],
+ codes=[1, 2,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,2,79])
+ wavy_rna = PathPatch(wavy_rna_path, linewidth=linewidth, edgecolor=edgecolor,
+ facecolor=color, zorder=12, linestyle='-')
+
+ ax.add_patch(wavy_rna)
+ # Add a label if needed
+ if opts != None and 'label' in list(opts.keys()):
+ if final_start > final_end:
+ write_label(ax, opts['label'], final_end+((final_start-final_end)/2.0), opts=opts)
+ else:
+ write_label(ax, opts['label'], final_start+((final_end-final_start)/2.0), opts=opts)
+ # Return the final start and end positions to the DNA renderer
+ if final_start > final_end:
+ return prev_end, final_start
+ else:
+ return prev_end, final_end
+
+
+def sbol_recombinase2 (ax, type, num, start, end, prev_end, scale, linewidth, opts):
+ """ SBOL recombinase site renderer - reverse direction
+ """
+ # Default parameters
+ color = (0,0,0)
+ color2 = (0,0,0)
+ start_pad = 0.0
+ end_pad = 0.0
+ x_extent = 12.0
+ y_extent = 12.0
+ linestyle = '-'
+ edgecolor = (0,0,0)
+ # Update default parameters if provided
+ if opts != None:
+ if 'start_pad' in list(opts.keys()):
+ start_pad = opts['start_pad']
+ if 'end_pad' in list(opts.keys()):
+ end_pad = opts['end_pad']
+ if 'x_extent' in list(opts.keys()):
+ x_extent = opts['x_extent']
+ if 'y_extent' in list(opts.keys()):
+ y_extent = opts['y_extent']
+ if 'linestyle' in list(opts.keys()):
+ linestyle = opts['linestyle']
+ if 'linewidth' in list(opts.keys()):
+ linewidth = opts['linewidth']
+ if 'scale' in list(opts.keys()):
+ scale = opts['scale']
+ if 'color' in list(opts.keys()):
+ color = opts['color']
+ if 'color2' in list(opts.keys()):
+ color2 = opts['color2']
+ else:
+ if 'color' in list(opts.keys()):
+ r2 = float(color[0]) / 2
+ g2 = float(color[1]) / 2
+ b2 = float(color[2]) / 2
+ color2 = (r2,g2,b2)
+ if 'edgecolor' in list(opts.keys()):
+ edgecolor = opts['edgecolor']
+ # Check direction add start padding
+ final_end = end
+ final_start = prev_end
+ y_lower = -1 * y_extent/2
+ y_upper = y_extent/2
+ if start > end:
+ #this is reverse
+ start = prev_end+end_pad+x_extent+linewidth
+ end = prev_end+end_pad+linewidth
+ final_end = start+start_pad+linewidth
+ #temp = color
+ #color = color2
+ #color2 = temp
+ else:
+ start = prev_end+start_pad+linewidth
+ end = start+x_extent
+ final_end = end+end_pad+linewidth
+ # Draw the site
+ #big triangle (the whole thing)
+ p1 = Polygon([(start, y_lower),
+ (start, y_upper),
+ (end,0)],
+ edgecolor=edgecolor, facecolor=color, linewidth=linewidth, zorder=11,
+ path_effects=[Stroke(joinstyle="miter")])
+ midpoint = (end + start) / 2
+ hypotenuse = math.sqrt( (y_extent/2)**2 + (x_extent)**2 )
+ hypotenuse2 = hypotenuse / 2
+ cosineA = (y_extent/2) / hypotenuse
+ f = hypotenuse2 * cosineA
+ #small triangle
+ p2 = Polygon([(midpoint, -1*f),
+ (midpoint, f),
+ (end,0)],
+ edgecolor=edgecolor, facecolor=color2, linewidth=linewidth, zorder=12,
+ path_effects=[Stroke(joinstyle="miter")])
+ ax.add_patch(p1)
+ ax.add_patch(p2)
+ # Add a label if needed
+ if opts != None and 'label' in list(opts.keys()):
+ if final_start > final_end:
+ write_label(ax, opts['label'], final_end+((final_start-final_end)/2.0), opts=opts)
+ else:
+ write_label(ax, opts['label'], final_start+((final_end-final_start)/2.0), opts=opts)
+ # Return the final start and end positions to the DNA renderer
+ if final_start > final_end:
+ return prev_end, final_start
+ else:
+ return prev_end, final_end
def sbol_restriction_site (ax, type, num, start, end, prev_end, scale, linewidth, opts):
@@ -1549,11 +1931,11 @@ def sbol_restriction_site (ax, type, num, start, end, prev_end, scale, linewidth
final_end = end
final_start = prev_end
- start = prev_end+start_pad
- end = start + linewidth
+ start = prev_end+start_pad+linewidth/2
+ end = start + linewidth/2
final_end = end+end_pad
-
- l1 = Line2D([start,start],[-y_extent,y_extent],
+
+ l1 = Line2D([start,start],[-y_extent,y_extent],
linewidth=linewidth, color=color, zorder=12+zorder_add, linestyle=linestyle)
ax.add_line(l1)
@@ -1606,7 +1988,7 @@ def sbol_spacer (ax, type, num, start, end, prev_end, scale, linewidth, opts):
# Check direction add start padding
final_end = end
final_start = prev_end
-
+
start = prev_end+start_pad
end = start+x_extent
final_end = end+end_pad
@@ -1616,13 +1998,13 @@ def sbol_spacer (ax, type, num, start, end, prev_end, scale, linewidth, opts):
delta = radius - 0.5 * radius * math.sqrt(2)
- l1 = Line2D([start+delta,end-delta],[radius-delta,-1*radius+delta],
+ l1 = Line2D([start+delta,end-delta],[radius-delta,-1*radius+delta],
linewidth=linewidth, color=edgecolor, zorder=12+zorder_add, linestyle=linestyle)
- l2 = Line2D([start+delta,end-delta],[-1*radius+delta,radius-delta],
+ l2 = Line2D([start+delta,end-delta],[-1*radius+delta,radius-delta],
linewidth=linewidth, color=edgecolor, zorder=12+zorder_add, linestyle=linestyle)
- c1 = Circle(rbs_center, x_extent/2.0, linewidth=linewidth, edgecolor=edgecolor,
+ c1 = Circle(rbs_center, x_extent/2.0, linewidth=linewidth, edgecolor=edgecolor,
facecolor=color, zorder=12+zorder_add)
-
+
ax.add_patch(c1)
ax.add_line(l1)
ax.add_line(l2)
@@ -1650,6 +2032,8 @@ def sbol_origin (ax, type, num, start, end, prev_end, scale, linewidth, opts):
x_extent = 10.0
y_extent = 10.0
linestyle = '-'
+ y_offset = 0
+ face_color = (1,1,1)
# Reset defaults if provided
if opts != None:
if 'zorder_add' in list(opts.keys()):
@@ -1670,20 +2054,97 @@ def sbol_origin (ax, type, num, start, end, prev_end, scale, linewidth, opts):
linewidth = opts['linewidth']
if 'scale' in list(opts.keys()):
scale = opts['scale']
+ if 'y_offset' in list(opts.keys()):
+ y_offset = opts['y_offset']
+ if 'face_color' in list(opts.keys()):
+ face_color = tuple(opts['face_color'])
# Check direction add start padding
final_end = end
final_start = prev_end
-
+
+ start = prev_end+start_pad
+ end = start+x_extent
+ final_end = end+end_pad
+ ori_center = (start+((end-start)/2.0),y_offset)
+
+ c1 = Circle(ori_center, x_extent/2.0, linewidth=linewidth, edgecolor=color,
+ facecolor=face_color, zorder=12+zorder_add)
+
+ ax.add_patch(c1)
+
+ if opts != None and 'label' in list(opts.keys()):
+ if final_start > final_end:
+ write_label(ax, opts['label'], final_end+((final_start-final_end)/2.0), opts=opts)
+ else:
+ write_label(ax, opts['label'], final_start+((final_end-final_start)/2.0), opts=opts)
+
+ if final_start > final_end:
+ return prev_end, final_start
+ else:
+ return prev_end, final_end
+
+def sbol_origin_of_transfer (ax, type, num, start, end, prev_end, scale, linewidth, opts):
+ """ Built-in SBOL origin of transfer renderer.
+ """
+ # Default options
+ zorder_add = 0.0
+ color = (0,0,0)
+ start_pad = 2.0
+ end_pad = 2.0
+ x_extent = 10.0
+ y_extent = 10.0
+ linestyle = '-'
+ # Reset defaults if provided
+ if opts != None:
+ if 'zorder_add' in list(opts.keys()):
+ zorder_add = opts['zorder_add']
+ if 'color' in list(opts.keys()):
+ color = opts['color']
+ if 'start_pad' in list(opts.keys()):
+ start_pad = opts['start_pad']
+ if 'end_pad' in list(opts.keys()):
+ end_pad = opts['end_pad']
+ if 'x_extent' in list(opts.keys()):
+ x_extent = opts['x_extent']
+ if 'y_extent' in list(opts.keys()):
+ y_extent = opts['y_extent']
+ if 'linestyle' in list(opts.keys()):
+ linestyle = opts['linestyle']
+ if 'linewidth' in list(opts.keys()):
+ linewidth = opts['linewidth']
+ if 'scale' in list(opts.keys()):
+ scale = opts['scale']
+ # Check direction add start padding
+ final_end = end
+ final_start = prev_end
+
start = prev_end+start_pad
end = start+x_extent
final_end = end+end_pad
ori_center = (start+((end-start)/2.0),0)
-
- c1 = Circle(ori_center, x_extent/2.0, linewidth=linewidth, edgecolor=color,
+ extend = 1.2
+ arrowlongedge = x_extent*extend*.20
+ arrowshortedge = x_extent*extend*.09
+ arrowdest = (start+x_extent*extend,y_extent*extend/2)
+
+ c1 = Circle(ori_center, x_extent/2.0, linewidth=linewidth, edgecolor=color,
facecolor=(1,1,1), zorder=12+zorder_add)
-
+ #arrow = FancyArrow(ori_center[0],ori_center[1],\
+ # x_extent/2*extend,y_extent/2*extend,width=linewidth)
+ arrowpath =Path(vertices=[ori_center,
+ arrowdest,
+ (arrowdest[0]-arrowlongedge,arrowdest[1]-arrowshortedge),
+ (arrowdest[0]-arrowshortedge,arrowdest[1]-arrowlongedge),
+ arrowdest,
+ arrowdest,],
+ codes=[1, 2,2,1,2,79])
+ p2 = PathPatch(arrowpath, linewidth=linewidth, edgecolor=color,
+ facecolor=(1,1,1), zorder=12+zorder_add, linestyle='-')
+
+
ax.add_patch(c1)
-
+ ax.add_patch(p2)
+
if opts != None and 'label' in list(opts.keys()):
if final_start > final_end:
write_label(ax, opts['label'], final_end+((final_start-final_end)/2.0), opts=opts)
@@ -1734,17 +2195,27 @@ def sbol_operator (ax, type, num, start, end, prev_end, scale, linewidth, opts):
start = prev_end+start_pad
end = start+x_extent
final_end = end+end_pad
-
+
#white rectangle overlays backbone line
- p1 = Polygon([(start, y_extent),
+
+ #p1 = Polygon([(start, y_extent),
+ # (start, -y_extent),
+ # (start+x_extent, -y_extent),
+ # (start+x_extent, y_extent)],
+ # edgecolor=(1,1,1), facecolor=(1,1,1), linewidth=None, zorder=11+zorder_add,
+ # path_effects=[Stroke(joinstyle="miter")]) # This is a work around for matplotlib < 1.4.0)
+ operatorpath = Path(vertices=[(start, y_extent),
(start, -y_extent),
(start+x_extent, -y_extent),
- (start+x_extent, y_extent)],
- edgecolor=(0,0,0), facecolor=(1,1,1), linewidth=linewidth, zorder=11+zorder_add,
- path_effects=[Stroke(joinstyle="miter")]) # This is a work around for matplotlib < 1.4.0)
+ (start+x_extent, y_extent),
+ (start, y_extent),
+ (start, y_extent)],
+ codes=[1, 2,2,2,1,79])
+ p2 = PathPatch(operatorpath, linewidth=linewidth, edgecolor=color,
+ facecolor=(1,1,1), zorder=11+zorder_add, linestyle='-')
+ #ax.add_patch(p1)
+ ax.add_patch(p2)
- ax.add_patch(p1)
-
if opts != None and 'label' in list(opts.keys()):
if final_start > final_end:
write_label(ax, opts['label'], final_end+((final_start-final_end)/2.0), opts=opts)
@@ -1768,6 +2239,7 @@ def sbol_insulator (ax, type, num, start, end, prev_end, scale, linewidth, opts)
x_extent = 8.0
y_extent = 4.0
linestyle = '-'
+ edgecolor = (0,0,0)
# Reset defaults if provided
if opts != None:
if 'zorder_add' in list(opts.keys()):
@@ -1788,21 +2260,23 @@ def sbol_insulator (ax, type, num, start, end, prev_end, scale, linewidth, opts)
linewidth = opts['linewidth']
if 'scale' in list(opts.keys()):
scale = opts['scale']
-
+ if 'edgecolor' in list(opts.keys()):
+ edgecolor = opts['edgecolor']
+
# Check direction add start padding
final_end = end
final_start = prev_end
start = prev_end+start_pad
end = start+x_extent
final_end = end+end_pad
-
+
#white rectangle overlays backbone line
- p1 = Polygon([(start, y_extent),
+ p1 = Polygon([(start, y_extent),
(start, -y_extent),
(start+x_extent, -y_extent),
(start+x_extent, y_extent)],
- edgecolor=(0,0,0), facecolor=(1,1,1), linewidth=linewidth, zorder=11+zorder_add,
- path_effects=[Stroke(joinstyle="miter")]) # This is a work around for matplotlib < 1.4.0)
+ edgecolor=edgecolor, facecolor=(1,1,1), linewidth=linewidth, zorder=11+zorder_add,
+ path_effects=[Stroke(joinstyle="miter")]) # This is a work around for matplotlib < 1.4.0)
bits = 5.0
gap_size = ((end-start)/bits)
@@ -1810,16 +2284,16 @@ def sbol_insulator (ax, type, num, start, end, prev_end, scale, linewidth, opts)
x_inset_end = start + ((bits-1.0)*gap_size)
# Inside rectangle
- p2 = Polygon([(x_inset_start, y_extent-gap_size),
+ p2 = Polygon([(x_inset_start, y_extent-gap_size),
(x_inset_start, -y_extent+gap_size),
(x_inset_end, -y_extent+gap_size),
(x_inset_end, y_extent-gap_size)],
- edgecolor=(0,0,0), facecolor=(1,1,1), linewidth=linewidth, zorder=12+zorder_add,
- path_effects=[Stroke(joinstyle="miter")]) # This is a work around for matplotlib < 1.4.0)
+ edgecolor=edgecolor, facecolor=(1,1,1), linewidth=linewidth, zorder=12+zorder_add,
+ path_effects=[Stroke(joinstyle="miter")]) # This is a work around for matplotlib < 1.4.0)
ax.add_patch(p1)
ax.add_patch(p2)
-
+
if opts != None and 'label' in list(opts.keys()):
if final_start > final_end:
write_label(ax, opts['label'], final_end+((final_start-final_end)/2.0), opts=opts)
@@ -1878,13 +2352,13 @@ def temporary_repressor (ax, type, num, start, end, prev_end, scale, linewidth,
start = prev_end+start_pad
end = start+x_extent
final_end = end+end_pad
-
+
e1center = (start+((end-start)/2.0),0)
e2center = (start+((end-start)/2.0)+x_extent/3.75,0)
- e1 = Ellipse(e1center, y_extent/2, y_extent, edgecolor=(0,0,0), facecolor=color,
+ e1 = Ellipse(e1center, y_extent/2, y_extent, edgecolor=(0,0,0), facecolor=color,
linewidth=linewidth, fill=True, zorder=12+zorder_add)
- e2 = Ellipse(e2center, y_extent/2, y_extent, edgecolor=(0,0,0), facecolor=color,
+ e2 = Ellipse(e2center, y_extent/2, y_extent, edgecolor=(0,0,0), facecolor=color,
linewidth=linewidth, fill=True, zorder=11+zorder_add)
ax.add_patch(e1)
@@ -1918,6 +2392,19 @@ def connect (ax, type, num, from_part, to_part, scale, linewidth, arc_height_ind
"""
regulation(ax, type, num, from_part, to_part, scale, linewidth, arc_height_index, opts)
+def bound(ax,type,num,from_part,to_part, scale, linewidth, arc_height_index, opts):
+ """renders a circle above a part to indicate that it is bound"""
+ color = (0.0,0.0,0.0)
+ circle_offset = 5
+ part_midpt = ((from_part['start'] + from_part['end']) / 2)
+ start = part_midpt- circle_offset
+ end = part_midpt + circle_offset
+ if('y_offset' not in opts):
+ opts['y_offset']=3
+ opts['y_offset'] = opts['y_offset']*arc_height_index
+ opts['x_extent']=circle_offset*2
+ opts['start_pad']=0
+ sbol_origin(ax,"Origin",0,start,end,start, 1.0,linewidth,opts)
def regulation (ax, type, num, from_part, to_part, scale, linewidth, arc_height_index, opts):
""" General function for drawing regulation arcs.
@@ -1933,7 +2420,7 @@ def regulation (ax, type, num, from_part, to_part, scale, linewidth, arc_height_
arcHeightEnd = arcHeightStart*1.5
arc_start_x_offset = 0.0
arc_end_x_offset = 0.0
-
+
# Reset defaults if provided
if opts != None:
if 'arrowhead_length' in list(opts.keys()):
@@ -1969,27 +2456,28 @@ def regulation (ax, type, num, from_part, to_part, scale, linewidth, arc_height_
top = arcHeight;
base = startHeight;
indHeight = arrowhead_length
- corr = linewidth
+ corr = .4*linewidth
+
if to_part['fwd'] == False:
base = -1*startHeight
arcHeightEnd = -arcHeightEnd
top = -1*arcHeight
indHeight = -1*arrowhead_length
- corr *= -1
+ corr *= -1.0
- line_away = Line2D([start,start],[base,top],
+ line_away = Line2D([start,start],[base,top],
linewidth=linewidth, color=color, zorder=12, linestyle=linestyle)
- line_across = Line2D([start,end],[top,top],
+ line_across = Line2D([start,end],[top,top],
linewidth=linewidth, color=color, zorder=12, linestyle=linestyle)
- line_toward = Line2D([end,end],[top,arcHeightEnd+corr],
+ line_toward = Line2D([end,end],[top,arcHeightEnd+corr],
linewidth=linewidth, color=color, zorder=12, linestyle=linestyle)
- line_rep = Line2D([end-arrowhead_length,end+arrowhead_length],[arcHeightEnd,arcHeightEnd],
+ line_rep = Line2D([end-arrowhead_length,end+arrowhead_length],[arcHeightEnd,arcHeightEnd],
linewidth=linewidth, color=color, zorder=12, linestyle='-')
- line_ind1 = Line2D([end-arrowhead_length,end],[arcHeightEnd+indHeight,arcHeightEnd],
+ line_ind1 = Line2D([end-arrowhead_length,end],[arcHeightEnd+indHeight,arcHeightEnd],
linewidth=linewidth, color=color, zorder=12, linestyle='-')
- line_ind2 = Line2D([end+arrowhead_length,end],[arcHeightEnd+indHeight,arcHeightEnd],
+ line_ind2 = Line2D([end+arrowhead_length,end],[arcHeightEnd+indHeight,arcHeightEnd],
linewidth=linewidth, color=color, zorder=12, linestyle='-')
if(type == 'Repression'):
@@ -1997,7 +2485,6 @@ def regulation (ax, type, num, from_part, to_part, scale, linewidth, arc_height_
ax.add_line(line_away)
ax.add_line(line_across)
ax.add_line(line_toward)
-
if(type == 'Activation'):
ax.add_line(line_ind1)
ax.add_line(line_ind2)
@@ -2058,26 +2545,26 @@ def trace_promoter_start (ax, type, num, start_bp, end_bp, prev_end, scale, line
dir_fac = -1.0
y_offset = -y_offset
# Draw the promoter symbol
- l1 = Line2D([start_bp,start_bp],[0+y_offset,dir_fac*y_extent+y_offset], linewidth=linewidth,
+ l1 = Line2D([start_bp,start_bp],[0+y_offset,dir_fac*y_extent+y_offset], linewidth=linewidth,
color=color, zorder=14+zorder_add)
l2 = Line2D([start_bp,start_bp+dir_fac*x_extent*scale-dir_fac*arrowhead_length*0.5*scale],
- [dir_fac*y_extent+y_offset,dir_fac*y_extent+y_offset], linewidth=linewidth,
+ [dir_fac*y_extent+y_offset,dir_fac*y_extent+y_offset], linewidth=linewidth,
color=color, zorder=14+zorder_add)
ax.add_line(l1)
ax.add_line(l2)
- p1 = Polygon([(start_bp+dir_fac*x_extent*scale-dir_fac*arrowhead_length*scale,
- dir_fac*y_extent+(arrowhead_height)+y_offset),
+ p1 = Polygon([(start_bp+dir_fac*x_extent*scale-dir_fac*arrowhead_length*scale,
+ dir_fac*y_extent+(arrowhead_height)+y_offset),
(start_bp+dir_fac*(x_extent*scale), dir_fac*y_extent+y_offset),
- (start_bp+dir_fac*x_extent*scale-dir_fac*arrowhead_length*scale,
+ (start_bp+dir_fac*x_extent*scale-dir_fac*arrowhead_length*scale,
dir_fac*y_extent-(arrowhead_height)+y_offset)],
- facecolor=color, edgecolor=color, linewidth=linewidth, zorder=14+zorder_add,
+ facecolor=color, edgecolor=color, linewidth=linewidth, zorder=14+zorder_add,
path_effects=[Stroke(joinstyle="miter")]) # This is a work around for matplotlib < 1.4.0)
ax.add_patch(p1)
# Shade the promoter area (normally smaller than symbol extent)
- p2 = Polygon([(start_bp, -highlight_y_extent+y_offset),
+ p2 = Polygon([(start_bp, -highlight_y_extent+y_offset),
(start_bp, highlight_y_extent+y_offset),
(end_bp, highlight_y_extent+y_offset),
- (end_bp, -highlight_y_extent+y_offset)], facecolor=color, edgecolor=color, linewidth=linewidth, zorder=14+zorder_add,
+ (end_bp, -highlight_y_extent+y_offset)], facecolor=color, edgecolor=color, linewidth=linewidth, zorder=14+zorder_add,
path_effects=[Stroke(joinstyle="miter")]) # This is a work around for matplotlib < 1.4.0)
ax.add_patch(p2)
if opts != None and 'label' in list(opts.keys()):
@@ -2130,26 +2617,26 @@ def trace_promoter (ax, type, num, start_bp, end_bp, prev_end, scale, linewidth,
dir_fac = -1.0
y_offset = -y_offset
# Draw the promoter symbol
- l1 = Line2D([end_bp,end_bp],[0+y_offset,dir_fac*y_extent+y_offset], linewidth=linewidth,
+ l1 = Line2D([end_bp,end_bp],[0+y_offset,dir_fac*y_extent+y_offset], linewidth=linewidth,
color=color, zorder=14+zorder_add)
l2 = Line2D([end_bp,end_bp+dir_fac*x_extent*scale-dir_fac*arrowhead_length*0.5*scale],
- [dir_fac*y_extent+y_offset,dir_fac*y_extent+y_offset], linewidth=linewidth,
+ [dir_fac*y_extent+y_offset,dir_fac*y_extent+y_offset], linewidth=linewidth,
color=color, zorder=14+zorder_add)
ax.add_line(l1)
ax.add_line(l2)
- p1 = Polygon([(end_bp+dir_fac*x_extent*scale-dir_fac*arrowhead_length*scale,
- dir_fac*y_extent+(arrowhead_height)+y_offset),
+ p1 = Polygon([(end_bp+dir_fac*x_extent*scale-dir_fac*arrowhead_length*scale,
+ dir_fac*y_extent+(arrowhead_height)+y_offset),
(end_bp+dir_fac*(x_extent*scale), dir_fac*y_extent+y_offset),
- (end_bp+dir_fac*x_extent*scale-dir_fac*arrowhead_length*scale,
+ (end_bp+dir_fac*x_extent*scale-dir_fac*arrowhead_length*scale,
dir_fac*y_extent-(arrowhead_height)+y_offset)],
- facecolor=color, edgecolor=color, linewidth=linewidth, zorder=14+zorder_add,
+ facecolor=color, edgecolor=color, linewidth=linewidth, zorder=14+zorder_add,
path_effects=[Stroke(joinstyle="miter")]) # This is a work around for matplotlib < 1.4.0)
ax.add_patch(p1)
# Shade the promoter area (normally smaller than symbol extent)
- p2 = Polygon([(start_bp, -highlight_y_extent+y_offset),
+ p2 = Polygon([(start_bp, -highlight_y_extent+y_offset),
(start_bp, highlight_y_extent+y_offset),
(end_bp, highlight_y_extent+y_offset),
- (end_bp, -highlight_y_extent+y_offset)], facecolor=color, edgecolor=color, linewidth=linewidth, zorder=14+zorder_add,
+ (end_bp, -highlight_y_extent+y_offset)], facecolor=color, edgecolor=color, linewidth=linewidth, zorder=14+zorder_add,
path_effects=[Stroke(joinstyle="miter")]) # This is a work around for matplotlib < 1.4.0)
ax.add_patch(p2)
if opts != None and 'label' in list(opts.keys()):
@@ -2201,10 +2688,10 @@ def trace_rbs (ax, type, num, start_bp, end_bp, prev_end, scale, linewidth, opts
c1 = Ellipse((start_bp,dir_fac*y_extent+y_offset),width=(x_extent*scale),height=y_extent*0.4,color=color, zorder=14+zorder_add)
ax.add_artist(c1)
# Shade the promoter area (normally smaller than symbol extent)
- p2 = Polygon([(start_bp, -highlight_y_extent+y_offset),
+ p2 = Polygon([(start_bp, -highlight_y_extent+y_offset),
(start_bp, highlight_y_extent+y_offset),
(end_bp, highlight_y_extent+y_offset),
- (end_bp, -highlight_y_extent+y_offset)], facecolor=color, edgecolor=color, linewidth=linewidth, zorder=14+zorder_add,
+ (end_bp, -highlight_y_extent+y_offset)], facecolor=color, edgecolor=color, linewidth=linewidth, zorder=14+zorder_add,
path_effects=[Stroke(joinstyle="miter")]) # This is a work around for matplotlib < 1.4.0)
ax.add_patch(p2)
if opts != None and 'label' in list(opts.keys()):
@@ -2248,12 +2735,12 @@ def trace_user_defined (ax, type, num, start_bp, end_bp, prev_end, scale, linewi
if start_bp > end_bp:
dir_fac = -1.0
# Draw the CDS symbol
- p1 = Polygon([(start_bp, y_extent+y_offset),
+ p1 = Polygon([(start_bp, y_extent+y_offset),
(start_bp, -y_extent+y_offset),
(end_bp-dir_fac*scale, -y_extent+y_offset),
(end_bp-dir_fac*scale, y_extent+y_offset)],
- edgecolor=(0.0,0.0,0.0), facecolor=color, linewidth=linewidth,
- hatch=hatch, zorder=15+zorder_add,
+ edgecolor=(0.0,0.0,0.0), facecolor=color, linewidth=linewidth,
+ hatch=hatch, zorder=15+zorder_add,
path_effects=[Stroke(joinstyle="miter")]) # This is a work around for matplotlib < 1.4.0)
ax.add_patch(p1)
if opts != None and 'label' in list(opts.keys()):
@@ -2303,15 +2790,15 @@ def trace_cds (ax, type, num, start_bp, end_bp, prev_end, scale, linewidth, opts
if start_bp > end_bp:
dir_fac = -1.0
# Draw the CDS symbol
- p1 = Polygon([(start_bp, y_extent+y_offset),
+ p1 = Polygon([(start_bp, y_extent+y_offset),
(start_bp, -y_extent+y_offset),
(end_bp-dir_fac*arrowhead_length*scale, -y_extent+y_offset),
(end_bp-dir_fac*arrowhead_length*scale, -y_extent-arrowhead_height+y_offset),
(end_bp, 0+y_offset),
(end_bp-dir_fac*arrowhead_length*scale, y_extent+arrowhead_height+y_offset),
(end_bp-dir_fac*arrowhead_length*scale, y_extent+y_offset)],
- edgecolor=(0.0,0.0,0.0), facecolor=color, linewidth=linewidth,
- hatch=hatch, zorder=15+zorder_add,
+ edgecolor=(0.0,0.0,0.0), facecolor=color, linewidth=linewidth,
+ hatch=hatch, zorder=15+zorder_add,
path_effects=[Stroke(joinstyle="miter")]) # This is a work around for matplotlib < 1.4.0)
ax.add_patch(p1)
if opts != None and 'label' in list(opts.keys()):
@@ -2363,10 +2850,10 @@ def trace_terminator (ax, type, num, start_bp, end_bp, prev_end, scale, linewidt
ax.add_line(l1)
ax.add_line(l2)
# Shade the terminator area (normally smaller than symbol extent)
- p2 = Polygon([(start_bp, -highlight_y_extent+y_offset),
+ p2 = Polygon([(start_bp, -highlight_y_extent+y_offset),
(start_bp, highlight_y_extent+y_offset),
(end_bp, highlight_y_extent+y_offset),
- (end_bp, -highlight_y_extent+y_offset)], facecolor=color, edgecolor=color, linewidth=linewidth, zorder=13,
+ (end_bp, -highlight_y_extent+y_offset)], facecolor=color, edgecolor=color, linewidth=linewidth, zorder=13,
path_effects=[Stroke(joinstyle="miter")]) # This is a work around for matplotlib < 1.4.0)
ax.add_patch(p2)
if opts != None and 'label' in list(opts.keys()):
@@ -2389,13 +2876,17 @@ class DNARenderer:
"""
# Standard part types
- STD_PART_TYPES = ['Promoter',
- 'CDS',
+ STD_PART_TYPES = ['Promoter',
+ 'Aptamer',
+ 'CDS',
'Terminator',
'RBS',
'Scar',
'Spacer',
'EmptySpace',
+ 'RecombinaseSite',
+ 'RecombinaseSite2',
+ 'NCRNA',
'Ribozyme',
'Ribonuclease',
'Protease',
@@ -2411,6 +2902,7 @@ class DNARenderer:
'StemTop',
'Operator',
'Origin',
+ 'OriginOfTransfer',
'Insulator',
'5Overhang',
'3Overhang',
@@ -2425,9 +2917,10 @@ class DNARenderer:
# Standard regulatory types
STD_REG_TYPES = ['Repression',
'Activation',
- 'Connection']
+ 'Connection',
+ 'Binding']
- def __init__(self, scale=1.0, linewidth=1.0, linecolor=(0,0,0),
+ def __init__(self, scale=1.0, linewidth=1.0, linecolor=(0,0,0),
backbone_pad_left=0.0, backbone_pad_right=0.0):
""" Constructor to generate an empty DNARenderer.
@@ -2456,15 +2949,19 @@ def SBOL_part_renderers (self):
""" Return dictionary of all standard built-in SBOL part renderers.
"""
return {
- 'Promoter' :sbol_promoter,
- 'CDS' :sbol_cds,
+ 'Promoter' :sbol_promoter,
+ 'Aptamer' :sbol_aptamer,
+ 'CDS' :sbol_cds,
'Terminator' :sbol_terminator,
'RBS' :sbol_rbs,
'Scar' :sbol_scar,
'Spacer' :sbol_spacer,
'EmptySpace' :sbol_empty_space,
'Ribozyme' :sbol_ribozyme,
+ 'NCRNA' :sbol_ncrna,
'Ribonuclease' :sbol_stem_top,
+ 'RecombinaseSite' :sbol_recombinase1,
+ 'RecombinaseSite2' :sbol_recombinase2,
'Protease' :sbol_stem_top,
'DNACleavageSite' :sbol_stem_top,
'RNACleavageSite' :sbol_stem_top,
@@ -2478,6 +2975,7 @@ def SBOL_part_renderers (self):
'StemTop' :sbol_stem_top,
'Operator' :sbol_operator,
'Origin' :sbol_origin,
+ 'OriginOfTransfer' :sbol_origin_of_transfer,
'Insulator' :sbol_insulator,
'5Overhang' :sbol_5_overhang,
'3Overhang' :sbol_3_overhang,
@@ -2493,21 +2991,22 @@ def trace_part_renderers (self):
""" Return dictionary of all standard built-in trace part renderers.
"""
return {
- 'Promoter' :trace_promoter,
- 'CDS' :trace_cds,
+ 'Promoter' :trace_promoter,
+ 'CDS' :trace_cds,
'Terminator' :trace_terminator,
'RBS' :trace_rbs,
- 'UserDefined' :trace_user_defined}
+ 'UserDefined' :trace_user_defined}
def std_reg_renderers (self):
""" Return dictionary of all standard built-in regulation renderers.
"""
return {
- 'Repression' :repress,
+ 'Repression' :repress,
'Activation' :induce,
- 'Connection' :connect}
+ 'Connection' :connect,
+ 'Binding':bound}
- def renderDNA (self, ax, parts, part_renderers, regs=None, reg_renderers=None, plot_backbone=True):
+ def renderDNA (self, ax, parts, part_renderers, regs=None, reg_renderers=None, plot_backbone=True,circular=False,circle_vheight=12):
""" Render the parts on the DNA and regulation.
Parameters
@@ -2519,7 +3018,7 @@ def renderDNA (self, ax, parts, part_renderers, regs=None, reg_renderers=None, p
The design to draw. This is a list of dicts, where each dict relates to
a part and must contain the following keys:
- name (string)
- - type (string)
+ - type (string)
- fwd (bool)
- start (float, optional)
- end (float, optional)
@@ -2533,12 +3032,12 @@ def renderDNA (self, ax, parts, part_renderers, regs=None, reg_renderers=None, p
Regulation present in the design. This is a list of dicts, where each dict
relates to a single regulation arc and must contain the following keys:
- type (string)
- - from_part (part object dict)
+ - from_part (part object dict)
- to_part (part object dict)
These will then be drawn in accordance with the renders selected.
reg_renderers : dict(functions) (default=None)
- Dict of functions where the key in the regulation type and the dictionary
+ Dict of functions where the key in the regulation type and the dictionary
returns the function to be used to draw that regulation type.
Returns
@@ -2555,7 +3054,7 @@ def renderDNA (self, ax, parts, part_renderers, regs=None, reg_renderers=None, p
matplotlib.rcParams['lines.solid_joinstyle'] = 'miter'
matplotlib.rcParams['lines.solid_capstyle'] = 'projecting'
# Make text editable in Adobe Illustrator
- matplotlib.rcParams['pdf.fonttype'] = 42
+ matplotlib.rcParams['pdf.fonttype'] = 42
# Plot the parts to the axis
part_num = 0
prev_end = 0
@@ -2570,11 +3069,13 @@ def renderDNA (self, ax, parts, part_renderers, regs=None, reg_renderers=None, p
if 'fwd' not in keys:
part['fwd'] = True
else:
- if part['fwd'] == False:
- start = part['start']
- end = part['end']
- part['end'] = start
- part['start'] = end
+ pass
+ #if part['fwd'] == False:
+ #if('start' in keys):
+ # start = part['start']
+ # end = part['end']
+ # part['end'] = start
+ # part['start'] = end
if 'start' not in keys:
if part['fwd'] == True:
part['start'] = part_num
@@ -2592,9 +3093,9 @@ def renderDNA (self, ax, parts, part_renderers, regs=None, reg_renderers=None, p
# Use the correct renderer
if 'renderer' in list(part.keys()):
# Use custom renderer
- prev_start, prev_end = part['renderer'](ax, part['type'], part_num,
+ prev_start, prev_end = part['renderer'](ax, part['type'], part_num,
part['start'], part['end'], prev_end,
- self.scale, self.linewidth,
+ self.scale, self.linewidth,
opts=part_opts)
#update start,end for regulation
@@ -2607,12 +3108,12 @@ def renderDNA (self, ax, parts, part_renderers, regs=None, reg_renderers=None, p
else:
# Use standard renderer, if one exists
if part['type'] in list(part_renderers.keys()):
- prev_start, prev_end = part_renderers[part['type']](ax,
- part['type'], part_num,
- part['start'], part['end'],
- prev_end, self.scale,
+ prev_start, prev_end = part_renderers[part['type']](ax,
+ part['type'], part_num,
+ part['start'], part['end'],
+ prev_end, self.scale,
self.linewidth, opts=part_opts)
-
+
#update start,end for regulation [TEG]
if part['fwd'] == True:
part['start'] = prev_start
@@ -2620,12 +3121,12 @@ def renderDNA (self, ax, parts, part_renderers, regs=None, reg_renderers=None, p
else:
part['start'] = prev_end
part['end'] = prev_start
-
+
if first_part == True:
first_start = prev_start
first_part = False
part_num += 1
-
+
# first pass to get all of the arcranges
if regs != None:
@@ -2639,12 +3140,15 @@ def renderDNA (self, ax, parts, part_renderers, regs=None, reg_renderers=None, p
reg_opts = None
if 'opts' in list(reg.keys()):
reg_opts = reg['opts']
-
+
if reg['type'] in list(reg_renderers.keys()):
-
+
##############################################################################
arcstart = (reg['from_part']['start'] + reg['from_part']['end']) / 2
- arcend = (reg['to_part']['start'] + reg['to_part']['end']) / 2
+ if(reg['from_part']==reg['to_part']):
+ arcend = arcstart+.1
+ else:
+ arcend = (reg['to_part']['start'] + reg['to_part']['end']) / 2
arcrange = [arcstart,arcend]
reg['arclength'] = math.fabs(arcstart-arcend)
reg['arc_height_index'] = 1
@@ -2669,20 +3173,23 @@ def renderDNA (self, ax, parts, part_renderers, regs=None, reg_renderers=None, p
reg_opts = None
if 'opts' in list(reg.keys()):
reg_opts = reg['opts']
-
+
if reg['type'] in list(reg_renderers.keys()):
-
+
##############################################################################
# arc height algorithm: greedy from left-to-right on DNA design
-
+
arcstart = (reg['from_part']['start'] + reg['from_part']['end']) / 2
- arcend = (reg['to_part']['start'] + reg['to_part']['end']) / 2
-
+ if(reg['from_part']==reg['to_part']):
+ arcend = arcstart+.1
+ else:
+ arcend = (reg['to_part']['start'] + reg['to_part']['end']) / 2
+
arcmin = min(arcstart,arcend)
arcmax = max(arcstart,arcend)
arcrange = [arcmin,arcmax,reg['arc_height_index']]
arc_height_index = 1
-
+
# arc above if to_part is fwd
if(reg['to_part']['fwd'] == True):
# find max arc height index of ONLY the prior arcs that clash with the current arc
@@ -2700,7 +3207,7 @@ def renderDNA (self, ax, parts, part_renderers, regs=None, reg_renderers=None, p
elif(arcrange[1] > r[1] and arcrange[0] < r[0]):
if(r[2] > current_max):
current_max = r[2]
-
+
# if arcs cross over, increment the arc height index
for r in pos_arc_ranges:
if (arcrange[0] > r[0] and arcrange[0] < r[1]):
@@ -2716,7 +3223,7 @@ def renderDNA (self, ax, parts, part_renderers, regs=None, reg_renderers=None, p
reg['arc_height_index'] = current_max + 1
arcrange[2] = reg['arc_height_index']
pos_arc_ranges.append(arcrange)
-
+
# arc below if to_part is reverse
else:
# find max arc height index
@@ -2734,7 +3241,7 @@ def renderDNA (self, ax, parts, part_renderers, regs=None, reg_renderers=None, p
elif(arcrange[1] > r[1] and arcrange[0] < r[0]):
if(r[2] > current_max):
current_max = r[2]
-
+
# if arcs cross over, increment the arc height index
for r in neg_arc_ranges:
if (arcrange[0] > r[0] and arcrange[0] < r[1]):
@@ -2751,16 +3258,31 @@ def renderDNA (self, ax, parts, part_renderers, regs=None, reg_renderers=None, p
arcrange[2] = reg['arc_height_index']
neg_arc_ranges.append(arcrange)
##############################################################################
- reg_renderers[reg['type']](ax, reg['type'],
- reg_num, reg['from_part'],
- reg['to_part'], self.scale,
+ reg_renderers[reg['type']](ax, reg['type'],
+ reg_num, reg['from_part'],
+ reg['to_part'], self.scale,
self.linewidth, reg['arc_height_index'], opts=reg_opts)
reg_num += 1
# Plot the backbone (z=1)
if plot_backbone == True:
- l1 = Line2D([first_start-self.backbone_pad_left,prev_end+self.backbone_pad_right],[0,0],
- linewidth=self.linewidth, color=self.linecolor, zorder=10)
- ax.add_line(l1)
+ if(circular):
+ circ_start = first_start-self.backbone_pad_left
+ circ_end = prev_end+self.backbone_pad_right
+ circle_vheight #this is the height of the oval.
+ curves = (circ_end-circ_start)*.1 #curves are 5% of the length, lengthwise
+ plasmid = FancyBboxPatch((circ_start-circle_vheight/2, -circle_vheight), \
+ (circ_end-circ_start)+circle_vheight, circle_vheight,\
+ fc="none",ec=self.linecolor, linewidth=self.linewidth, \
+ boxstyle='round,pad=0,rounding_size={}'.format(circle_vheight/2), \
+ joinstyle="round", capstyle='round',mutation_aspect=1, zorder=5)
+ ax.add_patch(plasmid)
+ first_start = first_start-circle_vheight/2
+ prev_end = prev_end+circle_vheight/2
+ else:
+ l1 = Line2D([first_start-self.backbone_pad_left,prev_end+self.backbone_pad_right],[0,0],
+ linewidth=self.linewidth, color=self.linecolor, zorder=5)
+
+ ax.add_line(l1)
return first_start, prev_end
def annotate (self, ax, part_renderers, part, annotate_zorder=1000):
@@ -2772,10 +3294,10 @@ def annotate (self, ax, part_renderers, part, annotate_zorder=1000):
else:
part['opts']['zorder_add'] = annotate_zorder
# Draw the part
- part_renderers[part['type']](ax,
- part['type'], 1,
- part['start'], part['end'],
- part['start'], self.scale,
+ part_renderers[part['type']](ax,
+ part['type'], 1,
+ part['start'], part['end'],
+ part['start'], self.scale,
self.linewidth, opts=part['opts'])
@@ -2790,7 +3312,7 @@ def plot_sbol_designs (axes, dna_designs, regulations=None, plot_params={}, plot
Parameters
----------
axes : list(matplotlib.axis)
- List of axis objects to plot the designs to.
+ List of axis objects to plot the designs to.
dna_designs : list(dict(design_information))
List of designs to plot.
@@ -2830,7 +3352,7 @@ def plot_sbol_designs (axes, dna_designs, regulations=None, plot_params={}, plot
if 'linewidth' in list(plot_params.keys()):
linewidth = plot_params['linewidth']
dr = DNARenderer(scale=scale, linewidth=linewidth,
- backbone_pad_left=left_pad,
+ backbone_pad_left=left_pad,
backbone_pad_right=right_pad)
# We default to the standard regulation renderers
@@ -2945,11 +3467,111 @@ def convert_attrib (attrib):
return attrib
-dpl_default_type_map = {'gene': 'CDS',
- 'promoter': 'Promoter',
+dpl_default_type_map = {'gene': 'CDS',
+ 'promoter': 'Promoter',
'terminator': 'Terminator',
'rbs': 'RBS'}
+def simple_plot_design(simple_design,label_size = 13, label_y_offset = -8,cmap ='Set3',cmap2 = 'Set2',ax=None,\
+ dna_renderer=None,circular=False,ylift=-12,simplereg = None,regs=None,reg_renderers=None,\
+ linewidth=3,edgecolor = (1,.2,.2)):
+ """a simpler way to plot a construct.
+ simple_design: list of "SimplePart" objects, containing
+ name: string name that is displayed below the object
+ dpl_type: string representing dnaplotlib type to display it as
+ direction: direction "forward" or "reverse"
+ added_opts: dictionary of "opts" as seen in other dna plot lib objects
+ label
+ simplereg: dictionary of lists which determines how to display regulation
+ {: [[from_item_index,to_item_index,name],
+ [from_item_index,to_item_index,name], ...]}
+ regs: normal dictionary of regulation elements like in dnaplotlib
+
+ other options self explanatory
+ """
+
+ cmap_obj = plt.get_cmap(cmap).colors
+ cmap2_obj = plt.get_cmap(cmap2).colors
+ color_count = 0
+ design_list = []
+ annotate_list = []
+ if(dna_renderer is None):
+ dr = DNARenderer(scale = 5,linewidth=linewidth,linecolor=edgecolor)
+ else:
+ dr = dna_renderer
+ for part in simple_design:
+ part_dict = {'type':part.dpl_type, 'name':'test', 'fwd':'forward'==part.direction,\
+ 'opts':{'label':part.name,'label_size':label_size,'label_y_offset':label_y_offset,\
+ 'color':cmap_obj[color_count],'color2':cmap2_obj[color_count]}}
+ if(part.added_opts is not None):
+ part_dict['opts'].update(part.added_opts)
+ color_count += 1
+ if(color_count >= len(cmap_obj) or color_count >= len(cmap2_obj)):
+ color_count = 0
+ design_list += [part_dict]
+ part_renderers = dr.SBOL_part_renderers()
+ if(ax is None):
+ figsize = (len(design_list)*.75,1.6)
+
+ fig = plt.figure(figsize=figsize)
+
+ ax = fig.add_axes([0,0,1,1])
+ plt.tight_layout(pad=0.01)
+ if(simplereg is not None):
+ regs = []
+
+ protein_color = 0
+ for regtype,reg_list in simplereg.items():
+ reg_labels = {}
+ for reg in reg_list:
+ from_part = design_list[reg[0]]
+ if(len(reg)==3):
+ to_part = design_list[reg[1]]
+ else:
+ to_part = from_part
+ binding_label = reg[-1]
+ if(binding_label in reg_labels):
+ fill_color = reg_labels[binding_label]
+ else:
+ fill_color = cmap2_obj[protein_color]
+ reg_labels[binding_label] = fill_color
+ protein_color += 1
+ if(protein_color >= len(cmap2_obj)):
+ protein_color = 0
+ arc = {'type':regtype, 'from_part':from_part, 'to_part':to_part, 'opts':{'label':binding_label,'label_size':label_size*.7,\
+ 'label_x_offset':-1,'color':'blue', 'linewidth':linewidth,'y_offset':10,'face_color':fill_color}}
+ regs += [arc]
+ if(reg_renderers is None):
+ reg_renderers = dr.std_reg_renderers()
+ start,end = dr.renderDNA(ax,design_list,part_renderers,circular=circular,regs=regs, reg_renderers=reg_renderers)
+
+ fig = ax.get_figure()
+
+ ylimits = [0,0]
+ xlimits = [0,0]
+ for patch in ax.patches:
+ bbox = patch.get_window_extent()
+ if(bbox.y1 > ylimits[1]):
+ ylimits[1] = bbox.y1
+ if(bbox.y0 < ylimits[0]):
+ ylimits[0] = bbox.y0
+
+ if(bbox.x1 > xlimits[1]):
+ xlimits[1] = bbox.x1
+ if(bbox.x0 < xlimits[0]):
+ xlimits[0] = bbox.x0
+ ylimits = [a/fig.dpi for a in ylimits]
+ xlimits = [a/fig.dpi for a in xlimits]
+ yheight = ylimits[1]-ylimits[0]
+ xheight = xlimits[1]-xlimits[0]
+
+ addedsize = 1
+ axis_xlim = [start-addedsize,end+addedsize]
+ fig.set_size_inches((axis_xlim[1]-axis_xlim[0])/yheight*1.5,1.5)
+ ax.axis('off')
+ ax.set_xlim(axis_xlim)
+ ax.set_ylim(ylimits)
+ return ax
def load_design_from_gff (filename, chrom, type_map=dpl_default_type_map, region=None):
# Load the GFF data
diff --git a/gallery/all_parts/README.md b/gallery/all_parts/README.md
index 0e65e4f..6c721a8 100644
--- a/gallery/all_parts/README.md
+++ b/gallery/all_parts/README.md
@@ -1,6 +1,6 @@
# SBOL Visual Parts & Customization
-
+
-Illustration of all SBOL Visual parts in forward and reverse direction. Each part can have its apperance customised to convay further information.
+Illustration of all SBOL Visual parts in forward and reverse direction. Each part can have its apperance customised to convey further information.
diff --git a/gallery/all_parts/actually_all_parts.png b/gallery/all_parts/actually_all_parts.png
new file mode 100644
index 0000000..7003862
Binary files /dev/null and b/gallery/all_parts/actually_all_parts.png differ
diff --git a/gallery/all_parts/actually_all_parts.py b/gallery/all_parts/actually_all_parts.py
new file mode 100644
index 0000000..4cf0e36
--- /dev/null
+++ b/gallery/all_parts/actually_all_parts.py
@@ -0,0 +1,39 @@
+#import sys
+import dnaplotlib as dpl
+import matplotlib.pyplot as plt
+#import matplotlib.transforms as mtransforms
+#import matplotlib.patches as mpatch
+#from matplotlib.patches import FancyBboxPatch
+import numpy as np
+
+dnaline = 3
+dr = dpl.DNARenderer(scale = 5,linewidth=dnaline)
+part_renderers = dr.SBOL_part_renderers()
+parts = part_renderers.keys()
+dontrender = ['StemTop']
+fig1 = plt.figure(figsize=(14,14))
+faxes = fig1.subplots(ncols=6,nrows=6)
+raxes = np.ravel(faxes)
+#print(raxes)
+raxind = 0
+for part in parts:
+ if(part in dontrender):
+ continue
+ ax = raxes[raxind]
+ raxind+=1
+ #plt.Figure(figsize=(.1,.1))
+ #ax = plt.gca()
+ design = [{'type':part, 'name':'test', 'fwd':True,\
+ 'opts':{'label':part,'label_size':13,'label_y_offset':-8,'color':(.5,.5,.2)}},
+ {'type':part, 'name':'testr', 'fwd':False,'opts':{'color':(.2,.5,.5)}}]
+ start,end = dr.renderDNA(ax,design,part_renderers)
+ ax.axis('off')
+ xdist = end-start
+ delta = xdist*.2
+ start-=delta
+ end+=delta
+ newxdist = end-start
+ ax.set_xlim([start,end])
+
+ ax.set_ylim([-newxdist/2,newxdist/2])
+plt.savefig("actually_all_parts.png")
diff --git a/gallery/notebooks/interactiveplot.ipynb b/gallery/notebooks/interactiveplot.ipynb
new file mode 100644
index 0000000..bb97371
--- /dev/null
+++ b/gallery/notebooks/interactiveplot.ipynb
@@ -0,0 +1,171 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "metadata": {},
+ "outputs": [
+ {
+ "output_type": "display_data",
+ "data": {
+ "text/plain": "",
+ "image/svg+xml": "\r\n\r\n\r\n\r\n",
+ "image/png": "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+HCufeYZPpkxg6oWZnV3Pp4+nWuefpqz77uPhUuX5nZ9DRyajaKllZ4sJS0bRV8T6sUSgDmLFnH6nXdy88iRTJk9u8pz3Z3/TpvGpU88wUWPPcayNWO7viQs2LeqitNFRERE1imaJroEZaNoYiaO9wOeBnoCPJLN8kg2S9/u3RkyaBDbbbopHdu2xQlP9Md+8QUjP/yQz+bOLUxuOjA0G0UaY7GOy0bR+5k4PgB4Eui6yp1733qLe996iwEbbcSQbbbhO5tsQoc2bVjtzqJly3hn6lReHDeOr+bPL0xuEnBANopmNvobkaKbNm8eXWfMKEpa8xcvLko60vQq+HtQZ4uW6vlYWkyaNYt5RZo2fPHy5UVJR6TYFOCUqGwUvZOJ4+2Bu4Ef5rZPnTOH20aNqmkyzwInZaOo6kf8ss7IRtGopF7cB+yR2z5h5kwmzKxxrPIA8ItsFC1ogCJKE7j66aebughSgn736KNNXQQpQWcNH97URRBpcOqiVsKyUTQLOBA4mHBDW5NHLouA4cBBwEEKbtInG0WfA/sAhwOPAjV5tDofuAP4AXCsghsRERFJK6tqTIeIiIiIiMi6RC04IiIiIiKSGgpwREREREQkNRTgiIiIiIhIaijAERERERGR1FCAIyIiIiIiqaEAR0REREREUkMBjoiIiIiIpIYCHBERERERSQ0FOCIiIiIikhoKcEREREREJDUU4IiIiIiISGoowBERERERkdRQgCMiIiIiIqmhAEdERERERFJDAY6IiIiIiKSGAhwREREREUkNBTgiIiIiIpIaCnBERERERCQ1FOCIiIiIiEhqKMAREREREZHUUIAjIiIiIiKpoQBHRERERERSQwGOiIiIiIikhgIcERERERFJDQU4IiIiIiKSGgpwREREREQkNRTgiIiIiIhIaijAERERERGR1FCAIyIiIiIiqaEAR0REREREUkMBjoiIiIiIpIYCHBERERERSQ0FOCIiIiIikhoKcEREREREJDUU4IiIiIiISGoowBERERERkdRQgCMiIiIiIqmhAEdERERERFJDAY6IiIiIiKSGAhwREREREUkNBTgiIiIiIpIaCnBERERERCQ1FOCIiIiIiEhqKMAREREREZHUaNXUBRARERERae7iOOO5/0dR1pqyLBXJxHF5+bJRVHLly6cWHBERERERSQ0FOCIiIiIikhoK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MEPa3ys4fwFhAdf9knNfIMzad2NN8icEaRsCjwNfE8ZgXQz8yt0fqeSc2wld9OYm77Wlu4+k6mtXMjQGR0REREREUkMtOCIiIiIikhoKcEREREREJDUU4IiIiIiISGoowBERERERkdRQgCMiIiIiIqmhAEdERERERFJDAY6IiIiIiKSGAhwREREREUkNBTgiIiIiIpIaCnBERERERCQ1FOCIiIiIiEhqKMAREREREZHUUIAjIiIiIiKpoQBHRERERERSQwGOiIiIiIikhgIcERERERFJDQU4IiIiIiKSGgpwREREREQkNRTgiIiIiIhIaijAERERERGR1FCAIyIiIiIiqaEAR0REREREUkMBjoiIiIiIpIYCHBERERERSQ0FOCIiIiIikhoKcEREREREJDUU4IiIiIiISGoowBERERERkdRQgCMiIiIiIqmhAEdERERERFJDAY6IiIiIiKSGAhwREREREUkNBTgiIiIiIpIaCnBERERERCQ1FOCIiIiIiEhqKMAREREREZHUUIAjIiIiIiKpoQBHRERERERSQwGOiIiIiIikhgIcERERERFJDQU4IiIiIiKSGgpwREREREQkNRTgiIiIiIhIaijAERERERGR1FCAIyIiIiIiqaEAR0REREREUkMBjoiIiIiIpIYCHBERERERSQ0FOCIiIiIikhoKcEREREREJDUU4IiIiIiISGoowBERERERkdRo1dQFaApxnPGaHBdFWSvGebWRieMa5ZGNom/lUZ9zRURERETSQC04IiIiIiKSGgpwREREREQkNZplF7WqupA1Rje0qlTVfaymXdCqS0dEREREJK3UgiMiIiIiIqmhAEdERERERFKjWXZRE2kocZwx4BLgkSjKjm/q8oiIiIg0NwpwRIqjM7DvTjsd8csxYx7eDzg/jjNHRlH2+aYumNRa+Vi3OM6Ub4yibGPkXZOxcw6QiePyDdkoaqjyFGrOY/tqPAayrqqobzWuFw2pijrXnOuFiJQgBTgidWPAjsD/JD+7LlmyoNUHHzyT298ZeCaOM+cDN0dRtsFvPkREREREY3BEamNj4ETgfmAWMAa4EtgTaLXeel046aTb6Nx5o9zxLYA/ArfFcaZNE5RXREREpNlRC45I5doCe7CmlWa76k7o2XMrTjvtHh566AKmTfsgt/lnQP84zhweRdk5DVZaERFpNDVd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\n"
+ },
+ "metadata": {
+ "needs_background": "light"
+ }
+ }
+ ],
+ "source": [
+ "#import sys\n",
+ "import dnaplotlib as dpl\n",
+ "import matplotlib.pyplot as plt\n",
+ "import numpy as np\n",
+ "\n",
+ "%matplotlib inline\n",
+ "dnaline = 3\n",
+ "edgecolor = (1,.2,.2)\n",
+ "\n",
+ "dr = dpl.DNARenderer(scale = 5,linewidth=dnaline,linecolor=edgecolor)\n",
+ "part_renderers = dr.SBOL_part_renderers()\n",
+ "parts = list(part_renderers.keys())+[['EmptySpace','circular test']]+['EmptySpace']*5\n",
+ "dontrender = ['StemTop']\n",
+ "fig1 = plt.figure(figsize=(14,14))\n",
+ "faxes = fig1.subplots(ncols=6,nrows=7)\n",
+ "raxes = np.ravel(faxes)\n",
+ "#print(raxes)\n",
+ "raxind = 0\n",
+ "\n",
+ "\n",
+ "\n",
+ "\n",
+ "\n",
+ "for part in parts:\n",
+ " if(part in dontrender):\n",
+ " continue\n",
+ " if(type(part)==list):\n",
+ " circMake = True\n",
+ " part = part[0]\n",
+ " partlabel = \"circular=True\"\n",
+ " else:\n",
+ " circMake = False\n",
+ " partlabel=part\n",
+ " ax = raxes[raxind]\n",
+ " raxind+=1\n",
+ " #plt.Figure(figsize=(.1,.1))\n",
+ " #ax = plt.gca()\n",
+ " design = [{'type':part, 'name':'test', 'fwd':True,\\\n",
+ " 'opts':{'label':partlabel,'label_size':13,'label_y_offset':-8,'color':(.5,.5,.2)}},\n",
+ " {'type':part, 'name':'testr', 'fwd':False,'opts':{'color':(.2,.5,.5),'edgecolor':edgecolor}}]\n",
+ " start,end = dr.renderDNA(ax,design,part_renderers,circular=circMake)\n",
+ " ax.axis('off')\n",
+ " xdist = end-start\n",
+ " delta = xdist*.2\n",
+ " start-=delta\n",
+ " end+=delta\n",
+ " newxdist = end-start\n",
+ " ax.set_xlim([start,end])\n",
+ " ax.set_ylim([-newxdist/len(design),newxdist/len(design)])\n",
+ "plt.show()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "metadata": {},
+ "outputs": [
+ {
+ "output_type": "stream",
+ "name": "stdout",
+ "text": [
+ "0\n"
+ ]
+ },
+ {
+ "output_type": "display_data",
+ "data": {
+ "text/plain": "",
+ "image/svg+xml": "\r\n\r\n\r\n\r\n",
+ "image/png": "iVBORw0KGgoAAAANSUhEUgAAA6gAAAB6CAYAAACyX36RAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4yLjIsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy+WH4yJAAAgAElEQVR4nO3de5zM9f4H8Nd71461bGXlsuQuESV2dBGHhMQSynFyi3ShIqTYCqtIIg5JYes4HVEo90ul8tucbqZc4pRyWVnWLbnGLruf3x/fmdnvrpm9zuc7l309H499mHnP9zvz2deM2XnP9/IRpRSIiIiIiIiI/C3M3wMgIiIiIiIiAtigEhERERERUYBgg0pEREREREQBgQ0qERERERERBQQ2qERERERERBQQ2KASERERERFRQGCDSkRERERERAGBDSoREREREREFBDaoREREREREFBDYoBIREREREVFAYINKREREREREAYENKhEREREREQUENqhEREREREQUENigEhERERERUUBgg0pEREREREQBgQ0qERERERERBQQ2qERERERERBQQ2KASERERERFRQGCDSkRERERERAGBDSoREREREREFBDaoREREREREFBDYoBIREREREVFAYINKREREREREAYENasBYUxtYE+HvURAREREREfkLG9TA0RfAbmDNw2xUiYiIiIioJGKDGlhqA3gHbFSJiIiIiKgEYoMamNioEhERERFRicMGNbCxUSUiIiIiohKDDWpwYKNKREREREQhjw1qcGGjSkREREREIYsNanBioxqERKSKv8dA1uHzbQ3mbA3mbA3mbA3mbA3mbI1QzFmUUv4eQ4hY488g9wO4H4jf6scxUD5EZCqA/yqlVvjj8Ses2qn9NTq+a2PR/RjBQkTWAxiqlNrj77GEMuZsDeZsDeZsDeZsDeZsjVDMmVtQg99GAP3ZnAaFMACLRaSFvwdClqgEYIOIVPL3QEIcc7YGc7YGc7YGc7YGc7ZGyOXMBjV4bQTQCohvD8Rv9vdgqMAiAawWkRv8PRCyRF0Aa0SkrL8HEuKYszWYszWYszWYszWYszVCKudS/h5AaIovwm6Oa8YCeKkAC24EMIFNaVCLgfFNVwulVJpVD1qY3W/NuwNzt91iaw7gQxHpppS67O/BhDDmbA3mbA3mbA3mbA3m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\n"
+ },
+ "metadata": {
+ "needs_background": "light"
+ }
+ }
+ ],
+ "source": [
+ "import dnaplotlib as dpl\n",
+ "import matplotlib.pyplot as plt\n",
+ "import numpy as np\n",
+ "from matplotlib import cm\n",
+ "from collections import OrderedDict\n",
+ "%matplotlib inline\n",
+ "\n",
+ "cmap = plt.get_cmap('Set3')\n",
+ "\n",
+ "dnaline = 3\n",
+ "edgecolor = (1,.2,.2)\n",
+ "\n",
+ "dr = dpl.DNARenderer(scale = 5,linewidth=dnaline,linecolor=edgecolor)\n",
+ "\n",
+ "\n",
+ "class SimplePart:\n",
+ " def __init__(self,name,dpl_type,direction='forward',bound=False,added_opts=None):\n",
+ " self.name = name\n",
+ " self.dpl_type = dpl_type\n",
+ " self.direction=direction\n",
+ " self.bound = bound\n",
+ " self.added_opts = added_opts\n",
+ "\n",
+ "\n",
+ "\n",
+ "\n",
+ "\n",
+ "\n",
+ "\n",
+ "prom = SimplePart('ptet','Promoter')\n",
+ "utr = SimplePart('utr1','RBS')\n",
+ "cds = SimplePart('gfp','CDS')\n",
+ "term = SimplePart('t16','Terminator')\n",
+ "aB = SimplePart('attB','RecombinaseSite')\n",
+ "aL = SimplePart('attL','RecombinaseSite2',direction=\"reverse\")\n",
+ "ori = SimplePart('','Origin',added_opts={'face_color':(0.5,0.5,.2)})\n",
+ "\n",
+ "\n",
+ "simple_arc = {'Binding':[[1,\"RNAP\"],[2,\"A\"],[2,\"B\"],[7,\"Bxb1\"],[5,\"Bxb1\"]]}\n",
+ "\n",
+ "a = dpl.simple_plot_design([aL,prom,utr,cds,term,cds,cds,cds,cds,cds,cds,cds],simplereg = {},circular=True)\n",
+ "\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {},
+ "outputs": [],
+ "source": []
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3.7.4 64-bit ('base': conda)",
+ "language": "python",
+ "name": "python37464bitbaseconda4bf18afa65be4bc0b1df4a316a30f53b"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.7.7-final"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
\ No newline at end of file
diff --git a/requirements.txt b/requirements.txt
index 0bc64fb..5b10244 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,2 +1,3 @@
matplotlib>=1.5.0
pysbol2
+numpy