Back to index

python-biopython  1.60
Classes | Functions | Variables
Bio.Graphics.BasicChromosome Namespace Reference

Classes

class  _ChromosomeComponent
class  Organism
class  Chromosome
class  ChromosomeSegment
class  AnnotatedChromosomeSegment
class  TelomereSegment
class  SpacerSegment

Functions

def _spring_layout
def _place_labels

Variables

tuple _color_trans = _ColorTranslator()

Detailed Description

Draw representations of organism chromosomes with added information.

These classes are meant to model the drawing of pictures of chromosomes.
This can be useful for lots of things, including displaying markers on
a chromosome (ie. for genetic mapping) and showing syteny between two
chromosomes.

The structure of these classes is intended to be a Composite, so that
it will be easy to plug in and switch different parts without
breaking the general drawing capabilities of the system. The
relationship between classes is that everything derives from
_ChromosomeComponent, which specifies the overall interface. The parts
then are related so that an Organism contains Chromosomes, and these
Chromosomes contain ChromosomeSegments. This representation differents
from the canonical composite structure in that we don't really have
'leaf' nodes here -- all components can potentially hold sub-components.

Most of the time the ChromosomeSegment class is what you'll want to
customize for specific drawing tasks.

For providing drawing capabilities, these classes use reportlab:

http://www.reportlab.com

This provides nice output in PDF, SVG and postscript.  If you have
reportlab's renderPM module installed you can also use PNG etc.

Function Documentation

def Bio.Graphics.BasicChromosome._place_labels (   desired_etc,
  minimum,
  maximum,
  gap = 0 
) [private]

Definition at line 569 of file BasicChromosome.py.

00569 
00570 def _place_labels(desired_etc, minimum, maximum, gap=0):
00571     desired_etc.sort()
00572     placed = _spring_layout([row[0] for row in desired_etc],
00573                             minimum, maximum, gap)
00574     for old,y2 in zip(desired_etc, placed):
00575         y1, color, name = old
00576         yield (y1, y2, color, name)

Here is the call graph for this function:

Here is the caller graph for this function:

def Bio.Graphics.BasicChromosome._spring_layout (   desired,
  minimum,
  maximum,
  gap = 0 
) [private]
Function to try and layout label co-ordinates (or other floats, PRIVATE).

Originally written for the y-axis vertical positioning of labels on a
chromosome diagram (where the minimum gap between y-axis co-ordinates is
the label height), it could also potentially be used for x-axis placement,
or indeed radial placement for circular chromosomes within GenomeDiagram.

In essence this is an optimisation problem, balancing the desire to have
each label as close as possible to its data point, but also to spread out
the labels to avoid overlaps. This could be described with a cost function
(modelling the label distance from the desired placement, and the inter-
label separations as springs) and solved as a multi-variable minimization
problem - perhaps with NumPy or SciPy.

For now however, the implementation is a somewhat crude ad hoc algorithm.

NOTE - This expects the input data to have been sorted!

Definition at line 480 of file BasicChromosome.py.

00480 
00481 def _spring_layout(desired, minimum, maximum, gap=0):
00482     """Function to try and layout label co-ordinates (or other floats, PRIVATE).
00483     
00484     Originally written for the y-axis vertical positioning of labels on a
00485     chromosome diagram (where the minimum gap between y-axis co-ordinates is
00486     the label height), it could also potentially be used for x-axis placement,
00487     or indeed radial placement for circular chromosomes within GenomeDiagram.
00488     
00489     In essence this is an optimisation problem, balancing the desire to have
00490     each label as close as possible to its data point, but also to spread out
00491     the labels to avoid overlaps. This could be described with a cost function
00492     (modelling the label distance from the desired placement, and the inter-
00493     label separations as springs) and solved as a multi-variable minimization
00494     problem - perhaps with NumPy or SciPy.
00495     
00496     For now however, the implementation is a somewhat crude ad hoc algorithm.
00497     
00498     NOTE - This expects the input data to have been sorted!
00499     """
00500     count = len(desired)
00501     if count <= 1:
00502         return desired #Easy!
00503     if minimum >= maximum:
00504         raise ValueError("Bad min/max %f and %f" % (minimum, maximum))
00505     if min(desired) < minimum or max(desired) > maximum:
00506         raise ValueError("Data %f to %f out of bounds (%f to %f)" \
00507                          % (min(desired), max(desired), minimum, maximum))
00508     equal_step = float(maximum - minimum) / (count - 1)
00509 
00510     if equal_step < gap:
00511         import warnings
00512         warnings.warn("Too many labels to avoid overlap")
00513         #Crudest solution
00514         return [minimum+i*equal_step for i in range(count)]
00515     
00516     good = True
00517     if gap:
00518         prev = desired[0]
00519         for next in desired[1:]:
00520             if prev - next < gap:
00521                 good = False
00522                 break
00523     if good:
00524         return desired
00525 
00526     span = maximum - minimum
00527     for split in [0.5*span, span/3.0, 2*span/3.0, 0.25*span, 0.75*span]:
00528         midpoint = minimum + split
00529         low = [x for x in desired if x <= midpoint - 0.5*gap]
00530         high = [x for x in desired if x > midpoint + 0.5*gap]
00531         if len(low)+len(high) < count:
00532             #Bad split point, points right on boundary
00533             continue
00534         elif not low and len(high)*gap <= (span-split) + 0.5*gap:
00535             #Give a little of the unused low space to the high points
00536             return _spring_layout(high, midpoint + 0.5*gap, maximum, gap)
00537         elif not high and len(low)*gap <= split + 0.5*gap:
00538             #Give a little of the unused highspace to the low points
00539             return _spring_layout(low, minimum, midpoint - 0.5*gap, gap)
00540         elif len(low)*gap <= split - 0.5*gap \
00541         and len(high)*gap <= (span-split) - 0.5*gap:
00542             return _spring_layout(low, minimum, midpoint - 0.5*gap, gap) + \
00543                    _spring_layout(high, midpoint+ 0.5*gap, maximum, gap)
00544     
00545     #This can be count-productive now we can split out into the telomere or
00546     #spacer-segment's vertical space...
00547     #Try not to spread out as far as the min/max unless needed
00548     low = min(desired)
00549     high = max(desired)
00550     if (high-low) / (count-1) >= gap:
00551         #Good, we don't need the full range, and can position the
00552         #min and max exactly as well :)
00553         equal_step = (high-low) / (count-1)
00554         return [low+i*equal_step for i in range(count)]
00555 
00556     low = 0.5 * (minimum + min(desired))
00557     high = 0.5 * (max(desired) + maximum)
00558     if (high-low) / (count-1) >= gap:
00559         #Good, we don't need the full range
00560         equal_step = (high-low) / (count-1)
00561         return [low+i*equal_step for i in range(count)]
00562 
00563     #Crudest solution
00564     return [minimum+i*equal_step for i in range(count)]
00565 
00566 #assert False, _spring_layout([0.10,0.12,0.13,0.14,0.5,0.75, 1.0], 0, 1, 0.1)
00567 #assert _spring_layout([0.10,0.12,0.13,0.14,0.5,0.75, 1.0], 0, 1, 0.1) == [0.0, 0.125, 0.25, 0.375, 0.5, 0.75, 1.0]
00568 #assert _spring_layout([0.10,0.12,0.13,0.14,0.5,0.75, 1.0], 0, 1, 0.1) == [0.0, 0.16666666666666666, 0.33333333333333331, 0.5, 0.66666666666666663, 0.83333333333333326, 1.0]

Here is the caller graph for this function:


Variable Documentation

tuple Bio.Graphics.BasicChromosome._color_trans = _ColorTranslator()

Definition at line 44 of file BasicChromosome.py.