Beispiel #1
0
def new_draw_pedigree(pedobj, gfilename='pedigree', gtitle='', gformat='jpg', \
    gsize='f', gdot=1, gorient='p', gdirec='', gname=0, garrow=1, \
    gtitloc='b', gtitjust='c', gshowall=1, gprog='dot'):
    """
    new_draw_pedigree() uses the pygraphviz to produce a directed graph of your
    pedigree with paths of inheritance as edges and animals as nodes.  If there
    is more than one generation in the pedigree as determind by the "gen"
    attributes of the animals in the pedigree, draw_pedigree() will use subgraphs
    to try and group animals in the same generation together in the drawing.

    Note that there is not (AFAIK) a nice way to get pygraphviz installed on vanilla
    Windows, so you'll have to make due with draw_pedigree() and plain old dot.
    """

    try:
        import pygraphviz
    except ImportError:
        if pedobj.kw['messages'] == 'verbose':
            print '[ERROR]: pyp_graphics/new_draw_pedigree() was unable to import the pygraphviz module!'
        logging.error(
            'pyp_graphics/new_draw_pedigree() was unable to import the pygraphviz module!'
        )
        return 0

    # Maps the 0/1 flags taken by the function and maps them to Python
    # True/False for settine edge and node attributes.
    _tf = {0: False, 1: True}

    from pyp_utils import string_to_table_name
    _gtitle = string_to_table_name(gtitle)

    if gtitloc not in ['t', 'b']:
        gtitloc = 'b'
    if gtitjust not in ['c', 'l', 'r']:
        gtitjust = 'c'

    if not pedobj.kw['pedigree_is_renumbered']:
        if pedobj.kw['messages'] != 'quiet':
            print '[GRAPH]: The pedigree that you passed to pyp_graphics/new_draw_pedigree() is not renumbered. Because of this, there may be errors in the rendered pedigree. In order to insure that the pedigree drawing is accurate, you should renumber the pedigree before calling new_draw_pedigree().'
        logging.error(
            'The pedigree that you passed to pyp_graphics/new_draw_pedigree() is not renumbered. Because of this, there may be errors in the rendered pedigree. In order to insure that the pedigree drawing is accurate, you should renumber the pedigree before calling new_draw_pedigree().'
        )

    # Create an empty pygraphviz graph using the Agraph class.
    g = pygraphviz.AGraph(directed=True, strict=False)

    # I'm not sure if I need to have this here or not.
    g.graph_attr['type'] = 'graph'

    # Name the graph -- _gtitle has the characters removed which would cause
    # dotfile processing to break.
    g.graph_attr['name'] = _gtitle

    # Set some properties for the graph.  The label attribute is based on the gtitle.
    # In cases where an empty string, e.g. '', is provided as the gtitle dot engine
    # processing breaks.  In such cases, don't add a label.

    if gtitle != '':
        g.graph_attr['label'] = gtitle
        g.graph_attr['labelloc'] = gtitloc
        g.graph_attr['labeljust'] = gtitjust

    # Set the page paper size and writeable area.
    g.graph_attr['page'] = '8.5,11'
    g.graph_attr['size'] = '7.5,10'

    # Set the page orientation.
    if gorient == 'l':
        g.graph_attr['orientation'] = 'landscape'
    else:
        g.graph_attr['orientation'] = 'portrait'

    if gsize != 'l':
        g.graph_attr['ratio'] = 'auto'
    if gdirec == 'RL':
        g.graph_attr['rankdir'] = 'RL'
    elif gdirec == 'LR':
        g.graph_attr['rankdir'] = 'LR'
    else:
        pass

    # Set a few other graph properties.
    g.graph_attr['center'] = 'True'
    g.graph_attr['concentrate'] = 'True'
    g.graph_attr['fontsize'] = str(pedobj.kw['default_fontsize'])
    g.graph_attr['ordering'] = 'out'

    for _m in pedobj.pedigree:
        # Add a node for the current animal and set some node properties.
        if gname:
            _node_name = _m.name
        else:
            _node_name = _m.animalID
        g.add_node(_node_name)
        n = g.get_node(_node_name)
        n.attr['shape'] = 'box'
        n.attr['fontname'] = 'Helvetica'
        n.attr['fontsize'] = str(pedobj.kw['default_fontsize'])
        n.attr['height'] = '0.35'
        #print '[DEBUG]: sex = ', _m.sex
        if _m.sex == 'M' or _m.sex == 'm':
            n.attr['shape'] = 'box'
        elif _m.sex == 'F' or _m.sex == 'f':
            n.attr['shape'] = 'ellipse'
        else:
            n.attr['shape'] = 'octagon'
            #pass

        # Add the edges to the parent nodes, if any.
        if int(_m.sireID) != pedobj.kw['missing_parent']:
            if gname:
                _sire_edge = pedobj.pedigree[int(_m.sireID) - 1].name
            else:
                # Check some outputs -- should I be using the animalID or the
                # originalID to assign edges? Nodes are based on the animalID,
                # so edges should also be in order to maintain consistency.
                #_sire_edge = pedobj.pedigree[int(_m.sireID)-1].originalID
                _sire_edge = pedobj.pedigree[int(_m.sireID) - 1].animalID
            g.add_edge(_sire_edge, _node_name)
            if not _tf[garrow]:
                #e = g.get_edge(_sire_edge,_anim_node)
                e = g.get_edge(_sire_edge, n)
                e.attr['dir'] = 'none'
        if int(_m.damID) != pedobj.kw['missing_parent']:
            if gname:
                _dam_edge = pedobj.pedigree[int(_m.damID) - 1].name
            else:
                _dam_edge = pedobj.pedigree[int(_m.damID) - 1].animalID
            g.add_edge(_dam_edge, _node_name)
            if not _tf[garrow]:
                #e = g.get_edge(_dam_edge,_anim_node)
                e = g.get_edge(_dam_edge, n)
                e.attr['dir'] = 'none'

    # For large graphs it is nice to write out the .dot file so that it does
    # not have to be recreated whenever new_draw_pedigree is called.
    # Especially when I am debugging.
    if gdot:
        dfn = '%s.dot' % (gfilename)
        try:
            g.write(dfn)
        except:
            if pedobj.kw['messages'] == 'verbose':
                print '[ERROR]: pyp_graphics/new_draw_pedigree() was unable to write the dotfile %s.' % (
                    dfn)
            logging.error(
                'pyp_graphics/new_draw_pedigree() was unable to draw the dotfile %s.',
                (dfn))

    # Write the graph to an output file.
    try:
        outfile = '%s.%s' % (gfilename, gformat)
        g.draw(outfile, prog=gprog)
        return 1
    except:
        outfile = '%s.%s' % (gfilename, gformat)
        if pedobj.kw['messages'] == 'verbose':
            print '[ERROR]: pyp_graphics/new_draw_pedigree() was unable to draw the pedigree %s.' % (
                outfile)
        logging.error(
            'pyp_graphics/new_draw_pedigree() was unable to draw the pedigree %s.',
            (outfile))
        return 0
Beispiel #2
0
def new_draw_colored_pedigree(pedobj, shading, gfilename='pedigree', \
    gtitle='', gformat='jpg', gsize='f', gdot=1, gorient='p', gdirec='', \
    gname=0, garrow=1, gtitloc='b', gtitjust='c', gshowall=1, gprog='dot', \
    ghatch='hatch'):
    """
    draw_pedigree() uses the pydot bindings to the graphviz library -- if they
    are available on your system -- to produce a directed graph of your pedigree
    with paths of inheritance as edges and animals as nodes.  If there is more than
    one generation in the pedigree as determind by the "gen" attributes of the animals
    in the pedigree, draw_pedigree() will use subgraphs to try and group animals in the
    same generation together in the drawing.
    """

    try:
        import pygraphviz
    except ImportError:
        if pedobj.kw['messages'] == 'verbose':
            print '[ERROR]: pyp_graphics/new_draw_pedigree() was unable to import the pygraphviz module!'
        logging.error(
            'pyp_graphics/new_draw_pedigree() was unable to import the pygraphviz module!'
        )
        return 0

    # Maps the 0/1 flags taken by the function and maps them to Python
    # True/False for settine edge and node attributes.
    _tf = {0: False, 1: True}

    from pyp_utils import string_to_table_name
    _gtitle = string_to_table_name(gtitle)

    if gtitloc not in ['t', 'b']:
        gtitloc = 'b'
    if gtitjust not in ['c', 'l', 'r']:
        gtitjust = 'c'

    if not pedobj.kw['pedigree_is_renumbered']:
        if pedobj.kw['messages'] != 'quiet':
            print '[GRAPH]: The pedigree that you passed to pyp_graphics/draw_pedigree() is not renumbered. Because of this, there may be errors in the rendered pedigree. In order to insure that the pedigree drawing is accurate, you should renumber the pedigree before calling draw_pedigree().'
        logging.error(
            'The pedigree that you passed to pyp_graphics/draw_pedigree() is not renumbered. Because of this, there may be errors in the rendered pedigree. In order to insure that the pedigree drawing is accurate, you should renumber the pedigree before calling draw_pedigree().'
        )

    # Create an empty pygraphviz graph using the Agraph class.
    g = pygraphviz.AGraph(directed=True, strict=False)

    # I'm not sure if I need to have this here or not.
    g.graph_attr['type'] = 'graph'

    # Name the graph -- _gtitle has the characters removed which would cause
    # dotfile processing to break.
    g.graph_attr['name'] = _gtitle

    # Set some properties for the graph.  The label attribute is based on the gtitle.
    # In cases where an empty string, e.g. '', is provided as the gtitle dot engine
    # processing breaks.  In such cases, don't add a label.

    if gtitle != '':
        g.graph_attr['label'] = gtitle
        g.graph_attr['labelloc'] = gtitloc
        g.graph_attr['labeljust'] = gtitjust

    # Set the page paper size and writeable area.
    g.graph_attr['page'] = '8.5,11'
    g.graph_attr['size'] = '7.5,10'

    # Set the page orientation.
    if gorient == 'l':
        g.graph_attr['orientation'] = 'landscape'
    else:
        g.graph_attr['orientation'] = 'portrait'

    if gsize != 'l':
        g.graph_attr['ratio'] = 'auto'
    if gdirec == 'RL':
        g.graph_attr['rankdir'] = 'RL'
    elif gdirec == 'LR':
        g.graph_attr['rankdir'] = 'LR'
    else:
        pass

    # Set a few other graph properties.
    g.graph_attr['center'] = 'True'
    g.graph_attr['concentrate'] = 'True'
    g.graph_attr['fontsize'] = str(pedobj.kw['default_fontsize'])
    g.graph_attr['ordering'] = 'out'

    # We need this for coloring the pedigree
    colormin = min(shading.values())
    colormax = max(shading.values())
    color_map = {}

    for _m in pedobj.pedigree:
        # Add a node for the current animal and set some node properties.
        if gname:
            _node_name = _m.name
        else:
            _node_name = _m.animalID
        g.add_node(_node_name)
        n = g.get_node(_node_name)
        n.attr['shape'] = 'box'
        n.attr['fontname'] = 'Helvetica'
        n.attr['fontsize'] = str(pedobj.kw['default_fontsize'])
        n.attr['height'] = '0.35'
        #print '[DEBUG]: sex = ', _m.sex
        if _m.sex == 'M' or _m.sex == 'm':
            n.attr['shape'] = 'box'
        elif _m.sex == 'F' or _m.sex == 'f':
            n.attr['shape'] = 'ellipse'
        else:
            n.attr['shape'] = 'octagon'
            #pass

        # Color the nodes
        if _m.userField == ghatch:
            n.attr['style'] = 'filled,peripheries=2'
        else:
            n.attr['style'] = 'filled'
            _color = get_color_32(shading[_m.animalID], colormin, colormax)
            n.attr['fillcolor'] = _color
            # Add values to the color map
            if not color_map.has_key(shading[_m.animalID]):
                color_map[shading[_m.animalID]] = _color

        # Add the edges to the parent nodes, if any.
        if _m.sireID != pedobj.kw['missing_parent']:
            if gname:
                _sire_edge = pedobj.pedigree[int(_m.sireID) - 1].name
            else:
                # Check some outputs -- should I be using the animalID or the
                # originalID to assign edges? Nodes are based on the animalID,
                # so edges should also be in order to maintain consistency.
                #_sire_edge = pedobj.pedigree[int(_m.sireID)-1].originalID
                _sire_edge = pedobj.pedigree[int(_m.sireID) - 1].animalID
            g.add_edge(_sire_edge, _node_name)
            if not _tf[garrow]:
                e = g.get_edge(_sire_edge, _anim_node)
                e.attr['dir'] = 'none'
        if _m.damID != pedobj.kw['missing_parent']:
            if gname:
                _dam_edge = pedobj.pedigree[int(_m.damID) - 1].name
            else:
                _dam_edge = pedobj.pedigree[int(_m.damID) - 1].animalID
            g.add_edge(_dam_edge, _node_name)
            if not _tf[garrow]:
                e = g.get_edge(_dam_edge, _anim_node)
                e.attr['dir'] = 'none'

    # For large graphs it is nice to write out the .dot file so that it does
    # not have to be recreated whenever new_draw_pedigree is called.
    # Especially when I am debugging.
    if gdot:
        dfn = '%s.dot' % (gfilename)
        try:
            g.write(dfn)
        except:
            if pedobj.kw['messages'] == 'verbose':
                print '[ERROR]: pyp_graphics/new_draw_pedigree() was unable to write the dotfile %s.' % (
                    dfn)
            logging.error(
                'pyp_graphics/new_draw_pedigree() was unable to draw the dotfile %s.',
                (dfn))

    # Write the color map to a file.
    #try:
    mapfile = '%s_color_map.txt' % (gfilename)
    mf = file(mapfile, 'w')
    mf.write('# Color map data\n')
    mf.write('# Data are metric (number of sons/descendants/etc.) followed\n')
    mf.write('# by color in RGB.\n')
    for k, v in color_map.iteritems():
        line = '%s\t%s\n' % (k, v)
        mf.write(line)
    mf.close()
    #except:
    #outfile = '%s_color_map.txt' % (gfilename)
    #if pedobj.kw['messages'] == 'verbose':
    #print '[ERROR]: pyp_jbc/new_draw_colored_pedigree() was unable to write the color map %s.' % (outfile)
    #logging.error('pyp_jbc/new_draw_colored_pedigree() was unable to write the color map %s.', (outfile))
    #return 0

    # Write the graph to an output file.
    #try:
    outfile = '%s.%s' % (gfilename, gformat)
    g.draw(outfile, prog=gprog)
    return 1
Beispiel #3
0
def draw_pedigree(pedobj,
                  gfilename='pedigree',
                  gtitle='',
                  gformat='jpg',
                  gsize='f',
                  gdot='1',
                  gorient='p',
                  gdirec='',
                  gname=0,
                  gfontsize=10,
                  garrow=1,
                  gtitloc='b',
                  gtitjust='c',
                  gshowall=1,
                  gclusters=0):
    """
    draw_pedigree() uses the pydot bindings to the graphviz library -- if they
    are available on your system -- to produce a directed graph of your pedigree
    with paths of inheritance as edges and animals as nodes.  If there is more than
    one generation in the pedigree as determind by the "gen" attributes of the animals
    in the pedigree, draw_pedigree() will use subgraphs to try and group animals in the
    same generation together in the drawing.
    """
    if gtitle == '':
        gtitle = pedobj.kw['pedname']
    from pyp_utils import string_to_table_name
    _gtitle = string_to_table_name(gtitle)
    #     if pedobj.kw['messages'] == 'verbose':
    #         print 'gtitle: %s' % ( gtitle )
    #         print '_gtitle: %s' % ( _gtitle )

    if gtitloc not in ['t', 'b']:
        gtitloc = 'b'
    if gtitjust not in ['c', 'l', 'r']:
        gtitjust = 'c'

    #print pedobj.metadata.unique_gen_list

    if not pedobj.kw['pedigree_is_renumbered']:
        if pedobj.kw['messages'] != 'quiet':
            print '[GRAPH]: The pedigree that you passed to pyp_graphics/draw_pedigree() is not renumbered. Because of this, there may be errors in the rendered pedigree. In order to insure that the pedigree drawing is accurate, you should renumber the pedigree before calling draw_pedigree().'
        logging.error(
            'The pedigree that you passed to pyp_graphics/draw_pedigree() is not renumbered. Because of this, there may be errors in the rendered pedigree. In order to insure that the pedigree drawing is accurate, you should renumber the pedigree before calling draw_pedigree().'
        )

    #try:
    import pydot
    # Set some properties for the graph.  The label attribute is based on the gtitle.
    # In cases where an empty string, e.g. '', is provided as the gtitle dot engine
    # processing breaks.  In such cases, don't add a label.
    if gtitle == '':
        if gshowall:
            g = pydot.Dot(graph_name=str(_gtitle),
                          graph_type='digraph',
                          strict=False,
                          suppress_disconnected=False,
                          simplify=True)
        else:
            g = pydot.Dot(graph_name=str(_gtitle),
                          graph_type='digraph',
                          strict=False,
                          suppress_disconnected=True,
                          simplify=True)
    else:
        if gshowall:
            g = pydot.Dot(label=str(_gtitle),
                          labelloc=str(gtitloc),
                          labeljust=str(gtitjust),
                          graph_name=str(_gtitle),
                          graph_type='digraph',
                          strict=False,
                          suppress_disconnected=False,
                          simplify=True)
        else:
            g = pydot.Dot(label=str(_gtitle),
                          labelloc=str(gtitloc),
                          labeljust=str(gtitjust),
                          graph_name=str(_gtitle),
                          graph_type='digraph',
                          strict=False,
                          suppress_disconnected=True,
                          simplify=True)
    # Make sure that gfontsize has a valid value.
    try:
        gfontsize = int(gfontsize)
    except:
        gfontsize = 10
    if gfontsize < 10:
        gfontsize = 10
    gfontsize = str(gfontsize)
    #     print 'gfontsize = %s' % (gfontsize)
    g.set_page("8.5,11")
    g.set_size("7.5,10")
    if gorient == 'l':
        g.set_orientation("landscape")
    else:
        g.set_orientation("portrait")
    if gsize != 'l':
        g.set_ratio("auto")
    if gdirec == 'RL':
        g.set_rankdir('RL')
    elif gdirec == 'LR':
        g.set_rankdir('LR')
    else:
        pass
    g.set_center('true')
    g.set_concentrate('true')
    g.set_ordering('out')
    if gformat not in g.formats:
        gformat = 'jpg'
    # If we do not have any generations, we have to draw a less-nice graph.
    if len(pedobj.metadata.unique_gen_list) <= 1:
        for _m in pedobj.pedigree:
            # Add a node for the current animal and set some properties.
            if gname:
                _node_name = _m.name
            else:
                _node_name = _m.animalID
            _an_node = pydot.Node(str(_node_name))
            _an_node.set_fontname('Helvetica')
            # _an_node.set_fontsize('10')
            _an_node.set_fontsize(str(gfontsize))
            _an_node.set_height('0.35')
            if _m.sex == 'M' or _m.sex == 'm':
                _an_node.set_shape('box')
            elif _m.sex == 'F' or _m.sex == 'f':
                _an_node.set_shape('ellipse')
            else:
                pass
            g.add_node(_an_node)
            # Add the edges to the parent nodes, if any.
            if int(_m.sireID) != pedobj.kw['missing_parent']:
                if gname:
                    if garrow:
                        g.add_edge(
                            pydot.Edge(
                                str(pedobj.pedigree[int(_m.sireID) - 1].name),
                                str(_m.name)))
                    else:
                        g.add_edge(
                            pydot.Edge(str(pedobj.pedigree[int(_m.sireID) -
                                                           1].name),
                                       str(_m.name),
                                       dir='none'))
                else:
                    if garrow:
                        g.add_edge(
                            pydot.Edge(
                                str(pedobj.pedigree[int(_m.sireID) -
                                                    1].originalID),
                                str(_m.originalID)))
                    else:
                        g.add_edge(
                            pydot.Edge(str(pedobj.pedigree[int(_m.sireID) -
                                                           1].originalID),
                                       str(_m.originalID),
                                       dir='none'))
            if int(_m.damID) != pedobj.kw['missing_parent']:
                if gname:
                    if garrow:
                        g.add_edge(
                            pydot.Edge(
                                str(pedobj.pedigree[int(_m.damID) - 1].name),
                                str(_m.name)))
                    else:
                        g.add_edge(
                            pydot.Edge(str(pedobj.pedigree[int(_m.damID) -
                                                           1].name),
                                       str(_m.name),
                                       dir='none'))
                else:
                    if garrow:
                        g.add_edge(
                            pydot.Edge(
                                str(pedobj.pedigree[int(_m.damID) -
                                                    1].originalID),
                                str(_m.originalID)))
                    else:
                        g.add_edge(
                            pydot.Edge(str(pedobj.pedigree[int(_m.damID) -
                                                           1].originalID),
                                       str(_m.originalID),
                                       dir='none'))
    # Or test the new subgraph clusters
    elif gclusters:
        for _g in pedobj.metadata.unique_gen_list:
            _sg_anims = []
            _sg_name = 'sg%s' % (_g)
            if gshowall:
                sg = pydot.Cluster(graph_name=str(_sg_name),
                                   suppress_disconnected=False,
                                   simplify=True)
            else:
                sg = pydot.Cluster(graph_name=str(_sg_name),
                                   suppress_disconnected=True,
                                   simplify=True)
            for _m in pedobj.pedigree:
                if int(_m.gen) == int(_g):
                    _sg_anims.append(_m.animalID)
                    # Add a node for the current animal and set some properties.
                    if gname:
                        _node_name = _m.name
                    else:
                        _node_name = str(_m.animalID)
                    _an_node = pydot.Node(str(_node_name))
                    _an_node.set_fontname('Helvetica')
                    _an_node.set_fontsize(gfontsize)
                    _an_node.set_height('0.35')
                    if _m.sex == 'M' or _m.sex == 'm':
                        _an_node.set_shape('box')
                    if _m.sex == 'F' or _m.sex == 'f':
                        _an_node.set_shape('ellipse')
                    sg.add_node(_an_node)
            g.add_subgraph(sg)
        # Now that we've added the clusters to the graph, define the
        # edges.
        for _m in pedobj.pedigree:
            if _m.sireID != pedobj.kw['missing_parent']:
                if gname:
                    if garrow:
                        g.add_edge(
                            pydot.Edge(
                                str(pedobj.pedigree[int(_m.sireID) - 1].name),
                                str(_m.name)))
                    else:
                        g.add_edge(
                            pydot.Edge(str(pedobj.pedigree[int(_m.sireID) -
                                                           1].name),
                                       str(_m.name),
                                       dir='none'))
                else:
                    if garrow:
                        g.add_edge(
                            pydot.Edge(
                                str(pedobj.pedigree[int(_m.sireID) -
                                                    1].animalID),
                                str(_m.animalID)))
                    else:
                        g.add_edge(
                            pydot.Edge(str(pedobj.pedigree[int(_m.sireID) -
                                                           1].animalID),
                                       str(_m.animalID),
                                       dir='none'))
            if _m.damID != pedobj.kw['missing_parent']:
                if gname:
                    if garrow:
                        g.add_edge(
                            pydot.Edge(
                                str(pedobj.pedigree[int(_m.damID) - 1].name),
                                str(_m.name)))
                    else:
                        g.add_edge(
                            pydot.Edge(str(pedobj.pedigree[int(_m.damID) -
                                                           1].name),
                                       str(_m.name),
                                       dir='none'))
                else:
                    if garrow:
                        g.add_edge(
                            pydot.Edge(
                                str(pedobj.pedigree[int(_m.damID) -
                                                    1].animalID),
                                str(_m.animalID)))
                    else:
                        g.add_edge(
                            pydot.Edge(str(pedobj.pedigree[int(_m.damID) -
                                                           1].animalID),
                                       str(_m.animalID),
                                       dir='none'))
    # Otherwise we can draw a nice graph.
    else:
        for _g in pedobj.metadata.unique_gen_list:
            _sg_anims = []
            _sg_name = 'sg%s' % (_g)
            if gshowall:
                sg = pydot.Subgraph(graph_name=str(_sg_name),
                                    suppress_disconnected=False,
                                    simplify=True,
                                    rank='same')
            else:
                sg = pydot.Subgraph(graph_name=str(_sg_name),
                                    suppress_disconnected=True,
                                    simplify=True,
                                    rank='same')
            for _m in pedobj.pedigree:
                if int(_m.gen) == int(_g):
                    _sg_anims.append(_m.animalID)
                    ## ->
                    # Add a node for the current animal and set some properties.
                    if gname:
                        _node_name = _m.name
                    else:
                        _node_name = str(_m.animalID)
                    _an_node = pydot.Node(str(_node_name))
                    _an_node.set_fontname('Helvetica')
                    _an_node.set_fontsize(str(gfontsize))
                    _an_node.set_height('0.35')
                    if _m.sex == 'M' or _m.sex == 'm':
                        _an_node.set_shape('box')
                    if _m.sex == 'F' or _m.sex == 'f':
                        _an_node.set_shape('ellipse')
                    sg.add_node(_an_node)
                    ## <-
                    # Add the edges to the parent nodes, if any.
                    if _m.sireID != pedobj.kw['missing_parent']:
                        if gname:
                            if garrow:
                                sg.add_edge(
                                    pydot.Edge(
                                        str(pedobj.pedigree[int(_m.sireID) -
                                                            1].name),
                                        str(_m.name)))
                            else:
                                sg.add_edge(
                                    pydot.Edge(str(
                                        pedobj.pedigree[int(_m.sireID) -
                                                        1].name),
                                               str(_m.name),
                                               dir='none'))
                        else:
                            if garrow:
                                sg.add_edge(
                                    pydot.Edge(
                                        str(pedobj.pedigree[int(_m.sireID) -
                                                            1].animalID),
                                        str(_m.animalID)))
                            else:
                                sg.add_edge(
                                    pydot.Edge(str(
                                        pedobj.pedigree[int(_m.sireID) -
                                                        1].animalID),
                                               str(_m.animalID),
                                               dir='none'))
                    if _m.damID != pedobj.kw['missing_parent']:
                        if gname:
                            if garrow:
                                sg.add_edge(
                                    pydot.Edge(
                                        str(pedobj.pedigree[int(_m.damID) -
                                                            1].name),
                                        str(_m.name)))
                            else:
                                sg.add_edge(
                                    pydot.Edge(str(
                                        pedobj.pedigree[int(_m.damID) -
                                                        1].name),
                                               str(_m.name),
                                               dir='none'))
                        else:
                            if garrow:
                                sg.add_edge(
                                    pydot.Edge(
                                        str(pedobj.pedigree[int(_m.damID) -
                                                            1].animalID),
                                        str(_m.animalID)))
                            else:
                                sg.add_edge(
                                    pydot.Edge(str(
                                        pedobj.pedigree[int(_m.damID) -
                                                        1].animalID),
                                               str(_m.animalID),
                                               dir='none'))
                    ## <-
            if len(_sg_anims) > 0:
                _sg_list = ''
                for _a in _sg_anims:
                    if len(_sg_list) == 0:
                        _sg_list = '%s' % (_a)
                    else:
                        _sg_list = '%s,%s' % (_sg_list, _a)
            sg.set_rank(_sg_list)
            g.add_subgraph(sg)
            #try:
            #print sg.get_node_list()
            #except:
            #print 'Could not get node list for subgraph!'
            #try:
            #print sg.get_edge_list()
            #except:
            #print 'Could not get edge list for subgraph!'

    # For large graphs it is nice to write out the .dot file so that it does
    # not have to be recreated whenever new_draw_pedigree is called.
    # Especially when I am debugging.
    if gdot:
        dfn = '%s.dot' % (gfilename)
        try:
            g.write(dfn)
        except:
            if pedobj.kw['messages'] == 'verbose':
                print '[ERROR]: pyp_graphics/draw_pedigree() was unable to write the dotfile %s.' % (
                    dfn)
            logging.error(
                'pyp_graphics/draw_pedigree() was unable to draw the dotfile %s.',
                (dfn))

    # Write the graph to an output file.
    try:
        outfile = '%s.%s' % (gfilename, gformat)
        g.write(outfile, prog='dot', format=gformat)
        return 1
    except:
        outfile = '%s.%s' % (gfilename, gformat)
        if pedobj.kw['messages'] == 'verbose':
            print '[ERROR]: pyp_graphics/draw_pedigree() was unable to draw the pedigree %s.' % (
                outfile)
        logging.error(
            'pyp_graphics/draw_pedigree() was unable to draw the pedigree %s.',
            (outfile))
        return 0
Beispiel #4
0
def draw_colored_pedigree(pedobj,
                          shading,
                          gfilename='pedigree',
                          gtitle='My_Pedigree',
                          gformat='jpg',
                          gsize='f',
                          gdot='1',
                          gorient='l',
                          gdirec='',
                          gname=0,
                          gfontsize=10,
                          garrow=1,
                          gtitloc='b',
                          gtitjust='c',
                          ghatch='hatch',
                          gprog='dot'):
    """
    draw_colored_pedigree() uses the pydot bindings to the graphviz library to produce a
    directed graph of your pedigree with paths of inheritance as edges and animals as
    nodes.  If there is more than one generation in the pedigree as determind by the "gen"
    attributes of the animals in the pedigree, draw_pedigree() will use subgraphs to try
    and group animals in the same generation together in the drawing.  Nodes will be
    colored based on the number of outgoing connections (number of offspring).
    """
    from pyp_utils import string_to_table_name
    _gtitle = string_to_table_name(gtitle)

    if gtitloc not in ['t', 'b']:
        gtitloc = 'b'
    if gtitjust not in ['c', 'l', 'r']:
        gtitjust = 'c'

    print '[DEBUG]: Entered draw_colored_pedigree()'

    #     try:
    import pydot

    # Build a list of generations -- if we have more than on, we can use the
    # "rank=same" option in dot to get nicer output.
    gens = pedobj.metadata.unique_gen_list
    # Set some properties for the graph.
    g = pydot.Dot(label=gtitle,
                  labelloc=gtitloc,
                  labeljust=gtitjust,
                  graph_name=_gtitle,
                  type='graph',
                  strict=False,
                  suppress_disconnected=True,
                  simplify=True)

    # Make sure that gfontsize has a valid value.
    try:
        gfontsize = int(gfontsize)
    except:
        gfontsize = 10
    if gfontsize < 10:
        gfontsize = 10
    gfontsize = str(gfontsize)
    #     print 'gfontsize = %s' % (gfontsize)
    g.set_page("8.5,11")
    g.set_size("7.5,10")
    if gorient == 'l':
        g.set_orientation("landscape")
    else:
        g.set_orientation("portrait")
    if gsize != 'l':
        g.set_ratio("auto")
    if gdirec == 'RL':
        g.set_rankdir('RL')
    elif gdirec == 'LR':
        g.set_rankdir('LR')
    else:
        pass
    g.set_center('true')
    g.set_concentrate('true')
    g.set_ordering('out')
    if gformat not in g.formats:
        gformat = 'jpg'
    # If we do not have any generations, we have to draw a less-nice graph.
    colormin = min(shading.values())
    colormax = max(shading.values())
    color_map = {}
    if len(gens) <= 1:
        animalCounter = 0
        print '\t[DEBUG]: Only one generation'
        for _m in pedobj.pedigree:
            animalCounter = animalCounter + 1
            if numpy.fmod(animalCounter, pedobj.kw['counter']) == 0:
                print '\t[DEBUG]: Records read: %s ' % (animalCounter)
            # Add a node for the current animal and set some properties.
            if gname:
                _node_name = _m.name
            else:
                _node_name = _m.animalID
            _an_node = pydot.Node(_node_name)
            _an_node.set_fontname('Helvetica')
            # _an_node.set_fontsize('10')
            _an_node.set_fontsize(gfontsize)
            _an_node.set_height('0.35')
            if _m.sex == 'M' or _m.sex == 'm':
                _an_node.set_shape('box')
            elif _m.sex == 'F' or _m.sex == 'f':
                _an_node.set_shape('ellipse')
            else:
                pass
            #print _m.userField, ghatch, ( _m.userField == ghatch )
            if _m.userField == ghatch:
                _an_node.set_style('filled,peripheries=2')
            else:
                _an_node.set_style('filled')
            try:
                _color = color_map[shading[_m.animalID]]
            except KeyError:
                _color = get_color_32(shading[_m.animalID], colormin, colormax)
                color_map[shading[_m.animalID]] = _color
                print '\t[DEBUG]: %s added to cache' % (_color)
            _an_node.set_fillcolor(_color)
            g.add_node(_an_node)
            # Add the edges to the parent nodes, if any.
            if _m.sireID != pedobj.kw['missing_parent']:
                if gname:
                    if garrow:
                        g.add_edge(
                            pydot.Edge(
                                pedobj.pedigree[int(_m.sireID) - 1].name,
                                _m.name))
                    else:
                        g.add_edge(
                            pydot.Edge(pedobj.pedigree[int(_m.sireID) -
                                                       1].name,
                                       _m.name,
                                       dir='none'))
                else:
                    if garrow:
                        g.add_edge(
                            pydot.Edge(
                                pedobj.pedigree[int(_m.sireID) - 1].originalID,
                                _m.originalID))
                    else:
                        g.add_edge(
                            pydot.Edge(pedobj.pedigree[int(_m.sireID) -
                                                       1].originalID,
                                       _m.originalID,
                                       dir='none'))
            if _m.damID != pedobj.kw['missing_parent']:
                if gname:
                    if garrow:
                        g.add_edge(
                            pydot.Edge(pedobj.pedigree[int(_m.damID) - 1].name,
                                       _m.name))
                    else:
                        g.add_edge(
                            pydot.Edge(pedobj.pedigree[int(_m.damID) - 1].name,
                                       _m.name,
                                       dir='none'))
                else:
                    if garrow:
                        g.add_edge(
                            pydot.Edge(
                                pedobj.pedigree[int(_m.damID) - 1].originalID,
                                _m.originalID))
                    else:
                        g.add_edge(
                            pydot.Edge(pedobj.pedigree[int(_m.damID) -
                                                       1].originalID,
                                       _m.originalID,
                                       dir='none'))
    # Otherwise we can draw a nice graph.
    else:
        for _g in gens:
            print '\t[DEBUG]: Looping over generations'
            _sg_anims = []
            _sg_name = 'sg%s' % (_g)
            sg = pydot.Subgraph(graph_name=_sg_name,
                                suppress_disconnected=True,
                                simplify=True)
            sg.set_simplify(True)
            animalCounter = 0
            for _m in pedobj.pedigree:
                animalCounter = animalCounter + 1
                if numpy.fmod(animalCounter, pedobj.kw['counter']) == 0:
                    print '\t[DEBUG]: Records read: %s ' % (animalCounter)
                if int(_m.gen) == int(_g):
                    _sg_anims.append(_m.animalID)
                # Add a node for the current animal and set some properties.
                if gname:
                    _node_name = _m.name
                else:
                    _node_name = _m.animalID
                _an_node = pydot.Node(_node_name)
                _an_node.set_fontname('Helvetica')
                _an_node.set_fontsize(gfontsize)
                _an_node.set_height('0.35')
                if _m.sex == 'M' or _m.sex == 'm':
                    _an_node.set_shape('box')
                elif _m.sex == 'F' or _m.sex == 'f':
                    _an_node.set_shape('ellipse')
                else:
                    pass
                if _m.userField == ghatch:
                    _an_node.set_style('filled,peripheries=2')
                else:
                    _an_node.set_style('filled')
                _color = get_color_32(shading[_m.animalID], colormin, colormax)
                _an_node.set_fillcolor(_color)
                sg.add_node(_an_node)
                # Add the edges to the parent nodes, if any.
                if _m.sireID != pedobj.kw['missing_parent']:
                    if gname:
                        if garrow:
                            sg.add_edge(
                                pydot.Edge(
                                    pedobj.pedigree[int(_m.sireID) - 1].name,
                                    _m.name))
                        else:
                            sg.add_edge(
                                pydot.Edge(pedobj.pedigree[int(_m.sireID) -
                                                           1].name,
                                           _m.name,
                                           dir='none'))
                    else:
                        if garrow:
                            sg.add_edge(
                                pydot.Edge(
                                    pedobj.pedigree[int(_m.sireID) -
                                                    1].originalID,
                                    _m.originalID))
                        else:
                            sg.add_edge(
                                pydot.Edge(pedobj.pedigree[int(_m.sireID) -
                                                           1].originalID,
                                           _m.originalID,
                                           dir='none'))
                #if int(_m.damID) != 0:
                if _m.damID != pedobj.kw['missing_parent']:
                    if gname:
                        if garrow:
                            sg.add_edge(
                                pydot.Edge(
                                    pedobj.pedigree[int(_m.damID) - 1].name,
                                    _m.name))
                        else:
                            sg.add_edge(
                                pydot.Edge(pedobj.pedigree[int(_m.damID) -
                                                           1].name,
                                           _m.name,
                                           dir='none'))
                    else:
                        if garrow:
                            sg.add_edge(
                                pydot.Edge(
                                    pedobj.pedigree[int(_m.damID) -
                                                    1].originalID,
                                    _m.originalID))
                        else:
                            sg.add_edge(
                                pydot.Edge(pedobj.pedigree[int(_m.damID) -
                                                           1].originalID,
                                           _m.originalID,
                                           dir='none'))
            if len(_sg_anims) > 0:
                _sg_list = ''
                for _a in _sg_anims:
                    if len(_sg_list) == 0:
                        _sg_list = 'same,%s' % (_a)
                    else:
                        _sg_list = '%s,%s' % (_sg_list, _a)
            sg.set_rank(_sg_list)
            g.add_subgraph(sg)
    # For large graphs it is nice to write out the .dot file so that it does not have to be recreated
    # whenever draw_pedigree is called.  Especially when I am debugging.  :-)
    if gdot:
        dfn = '%s.dot' % (gfilename)
        #             try:
        g.write(dfn)
#             except:
#                 pass
# Write the graph to an output file.
    outfile = '%s.%s' % (gfilename, gformat)
    if gprog not in ['dot', 'neato', 'none']:
        gprog = 'dot'
    if gprog != 'none':
        g.write(outfile, prog=gprog, format=gformat)
    return 1
Beispiel #5
0
def new_draw_pedigree(pedobj, gfilename='pedigree', gtitle='', gformat='jpg', \
    gsize='f', gdot=1, gorient='p', gdirec='', gname=0, garrow=1, \
    gtitloc='b', gtitjust='c', gshowall=1, gprog='dot'):
    """
    new_draw_pedigree() uses the pygraphviz to produce a directed graph of your
    pedigree with paths of inheritance as edges and animals as nodes.  If there
    is more than one generation in the pedigree as determined by the "gen"
    attributes of the animals in the pedigree, draw_pedigree() will use subgraphs
    to try and group animals in the same generation together in the drawing.

    Note that there is not (AFAIK) a nice way to get pygraphviz installed on vanilla
    Windows, so you'll have to make due with draw_pedigree() and plain old dot.
    """

    try:
        import pygraphviz
    except ImportError:
        if pedobj.kw['messages'] == 'verbose':
            print '[ERROR]: pyp_graphics/new_draw_pedigree() was unable to import the pygraphviz module!'
        logging.error('pyp_graphics/new_draw_pedigree() was unable to import the pygraphviz module!')
        return 0

    # Maps the 0/1 flags taken by the function and maps them to Python
    # True/False for settine edge and node attributes.
    _tf = {0:False, 1:True}

    from pyp_utils import string_to_table_name
    _gtitle = string_to_table_name(gtitle)

    if gtitloc not in ['t','b']:
        gtitloc = 'b'
    if gtitjust not in ['c','l','r']:
        gtitjust = 'c'

    if not pedobj.kw['pedigree_is_renumbered']:
        if pedobj.kw['messages'] != 'quiet':
            print '[GRAPH]: The pedigree that you passed to pyp_graphics/new_draw_pedigree() is not renumbered. Because of this, there may be errors in the rendered pedigree. In order to insure that the pedigree drawing is accurate, you should renumber the pedigree before calling new_draw_pedigree().'
        logging.error('The pedigree that you passed to pyp_graphics/new_draw_pedigree() is not renumbered. Because of this, there may be errors in the rendered pedigree. In order to insure that the pedigree drawing is accurate, you should renumber the pedigree before calling new_draw_pedigree().')

    # Create an empty pygraphviz graph using the Agraph class.
    g = pygraphviz.AGraph(directed=True,strict=False)

    # I'm not sure if I need to have this here or not.
    g.graph_attr['type'] = 'graph'

    # Name the graph -- _gtitle has the characters removed which would cause
    # dotfile processing to break.
    g.graph_attr['name'] = _gtitle

    # Set some properties for the graph.  The label attribute is based on the gtitle.
    # In cases where an empty string, e.g. '', is provided as the gtitle dot engine
    # processing breaks.  In such cases, don't add a label.

    if gtitle != '':
        g.graph_attr['label'] = gtitle
        g.graph_attr['labelloc'] = gtitloc
        g.graph_attr['labeljust'] = gtitjust

    # Set the page paper size and writeable area.
    g.graph_attr['page'] = '8.5,11'
    g.graph_attr['size'] = '7.5,10'

    # Set the page orientation.
    if gorient == 'l':
        g.graph_attr['orientation'] = 'landscape'
    else:
        g.graph_attr['orientation'] = 'portrait'

    if gsize != 'l':
        g.graph_attr['ratio'] = 'auto'
    if gdirec == 'RL':
        g.graph_attr['rankdir'] = 'RL'
    elif gdirec == 'LR':
        g.graph_attr['rankdir'] = 'LR'
    else:
        pass

    # Set a few other graph properties.
    g.graph_attr['center'] = 'True'
    g.graph_attr['concentrate'] = 'True'
    g.graph_attr['fontsize'] = str(pedobj.kw['default_fontsize'])
    g.graph_attr['ordering'] = 'out'

    for _m in pedobj.pedigree:
        # Add a node for the current animal and set some node properties.
        if gname:
            _node_name = _m.name
        else:
            _node_name = _m.animalID
        g.add_node(_node_name)
        n = g.get_node(_node_name)
        n.attr['shape'] = 'box'
        n.attr['fontname'] = 'Helvetica'
        n.attr['fontsize'] = str(pedobj.kw['default_fontsize'])
        n.attr['height'] = '0.35'
        #print '[DEBUG]: sex = ', _m.sex
        if _m.sex == 'M' or _m.sex == 'm':
            n.attr['shape'] = 'box'
        elif _m.sex == 'F' or _m.sex == 'f':
            n.attr['shape'] = 'ellipse'
        else:
            n.attr['shape'] = 'octagon'
            #pass

        # Add the edges to the parent nodes, if any.
        if int(_m.sireID) != pedobj.kw['missing_parent']:
            if gname:
                _sire_edge = pedobj.pedigree[int(_m.sireID)-1].name
            else:
                # Check some outputs -- should I be using the animalID or the
                # originalID to assign edges? Nodes are based on the animalID,
                # so edges should also be in order to maintain consistency.
                #_sire_edge = pedobj.pedigree[int(_m.sireID)-1].originalID
                _sire_edge = pedobj.pedigree[int(_m.sireID)-1].animalID
            g.add_edge(_sire_edge,_node_name)
            if not _tf[garrow]:
                #e = g.get_edge(_sire_edge,_anim_node)
		e = g.get_edge(_sire_edge,n)
                e.attr['dir'] = 'none'
        if int(_m.damID) != pedobj.kw['missing_parent']:
            if gname:
                _dam_edge = pedobj.pedigree[int(_m.damID)-1].name
            else:
                _dam_edge = pedobj.pedigree[int(_m.damID)-1].animalID
            g.add_edge(_dam_edge,_node_name)
            if not _tf[garrow]:
                #e = g.get_edge(_dam_edge,_anim_node)
		e = g.get_edge(_dam_edge,n)
                e.attr['dir'] = 'none'

    # For large graphs it is nice to write out the .dot file so that it does
    # not have to be recreated whenever new_draw_pedigree is called.
    # Especially when I am debugging.
    if gdot:
        dfn = '%s.dot' % (gfilename)
        try:
            g.write(dfn)
        except:
            if pedobj.kw['messages'] == 'verbose':
                print '[ERROR]: pyp_graphics/new_draw_pedigree() was unable to write the dotfile %s.' % (dfn)
            logging.error('pyp_graphics/new_draw_pedigree() was unable to draw the dotfile %s.', (dfn))

    # Write the graph to an output file.
    try:
        outfile = '%s.%s' % (gfilename,gformat)
        g.draw(outfile,prog=gprog)
        return 1
    except:
        outfile = '%s.%s' % (gfilename,gformat)
        if pedobj.kw['messages'] == 'verbose':
            print '[ERROR]: pyp_graphics/new_draw_pedigree() was unable to draw the pedigree %s.' % (outfile)
        logging.error('pyp_graphics/new_draw_pedigree() was unable to draw the pedigree %s.', (outfile))
        return 0
Beispiel #6
0
def draw_pedigree(pedobj, gfilename='pedigree', gtitle='', gformat='jpg', gsize='f', gdot='1', gorient='p', gdirec='', gname=0, gfontsize=10, garrow=1, gtitloc='b', gtitjust='c', gshowall=1, gclusters=0, gwidth=8.5, gheight=11, gdpi=150):
    """
    draw_pedigree() uses the pydot bindings to the graphviz library -- if they
    are available on your system -- to produce a directed graph of your pedigree
    with paths of inheritance as edges and animals as nodes.  If there is more than
    one generation in the pedigree as determind by the "gen" attributes of the animals
    in the pedigree, draw_pedigree() will use subgraphs to try and group animals in the
    same generation together in the drawing.
    """
    if gtitle == '':
        gtitle = pedobj.kw['pedname']
    from pyp_utils import string_to_table_name
    _gtitle = string_to_table_name(gtitle)
#     if pedobj.kw['messages'] == 'verbose':
#         print 'gtitle: %s' % ( gtitle )
#         print '_gtitle: %s' % ( _gtitle )

    if gtitloc not in ['t','b']:
        gtitloc = 'b'
    if gtitjust not in ['c','l','r']:
        gtitjust = 'c'

    #print pedobj.metadata.unique_gen_list

    if not pedobj.kw['pedigree_is_renumbered']:
        if pedobj.kw['messages'] != 'quiet':
            print '[GRAPH]: The pedigree that you passed to pyp_graphics/draw_pedigree() is not renumbered. Because of this, there may be errors in the rendered pedigree. In order to insure that the pedigree drawing is accurate, you should renumber the pedigree before calling draw_pedigree().'
        logging.error('The pedigree that you passed to pyp_graphics/draw_pedigree() is not renumbered. Because of this, there may be errors in the rendered pedigree. In order to insure that the pedigree drawing is accurate, you should renumber the pedigree before calling draw_pedigree().')

    #try:
    import pydot
    # Set some properties for the graph.  The label attribute is based on the gtitle.
    # In cases where an empty string, e.g. '', is provided as the gtitle dot engine
    # processing breaks.  In such cases, don't add a label.
    if gtitle == '':
        if gshowall:
            g = pydot.Dot(graph_name=str(_gtitle), graph_type='digraph', strict=False, suppress_disconnected=False, simplify=True)
        else:
            g = pydot.Dot(graph_name=str(_gtitle), graph_type='digraph', strict=False, suppress_disconnected=True, simplify=True)
    else:
        if gshowall:
            g = pydot.Dot(label=str(_gtitle), labelloc=str(gtitloc), labeljust=str(gtitjust), graph_name=str(_gtitle), graph_type='digraph', strict=False, suppress_disconnected=False, simplify=True)
        else:
            g = pydot.Dot(label=str(_gtitle), labelloc=str(gtitloc), labeljust=str(gtitjust), graph_name=str(_gtitle), graph_type='digraph', strict=False, suppress_disconnected=True, simplify=True)
    # Make sure that gfontsize has a valid value.
    try:
        gfontsize = int(gfontsize)
    except:
        gfontsize = 10
    if gfontsize < 10:
        gfontsize = 10
    gfontsize = str(gfontsize)
#     print 'gfontsize = %s' % (gfontsize)
    # Check the resolution and set if it's a positive integer, otherwise set it to the default.
    dpi = int(gdpi)
    if dpi <= 0: dpi = 150
    g.set_dpi(dpi)
    # If the user specifies a height and width for the canvas use it if it's a plausible
    # value. Anything smaller than 8.5 x 11 is set to that size. Values larger than 8.5 x 11
    # are left alone.
    if gheight and gwidth:
        gheight = float(gheight)
	gwidth = float(gwidth)
        if gwidth <= 8.5: gwidth = 8.5
        if gheight <= 11.: gwidth = 11.
        try:
            page = "%.1f,%.1f" % ( gwidth, gheight )
            size = "%.1f,%.1f" % ( gwidth-1, gheight-1 )
        except:
            page = "8.5,11"
            size = "7.5,10"
    else:
        page = "8.5,11"
        size = "7.5,10"
    g.set_page(page)
    g.set_size(size)
    # Handle the orientation of the document.
    if gorient == 'l':
        g.set_orientation("landscape")
    else:
        g.set_orientation("portrait")
    if gsize != 'l':
        g.set_ratio("auto")
    if gdirec not in ['RL', 'LR', 'TB', 'BT']:
        gdirec = 'TB'
    g.set_rankdir(gdirec)
    g.set_center('true')
    g.set_concentrate('true')
    g.set_ordering('out')
    if gformat not in g.formats:
        gformat = 'jpg'
    # If we do not have any generations, we have to draw a less-nice graph.
    if len(pedobj.metadata.unique_gen_list) <= 1:
        for _m in pedobj.pedigree:
            # Add a node for the current animal and set some properties.
            if str(_m.animalID) != str(pedobj.kw['missing_parent']):
                if gname:
                    _node_name = _m.name
                else:
                    _node_name = _m.animalID
                _an_node = pydot.Node(str(_node_name))
                _an_node.set_fontname('Helvetica')
                # _an_node.set_fontsize('10')
                _an_node.set_fontsize(str(gfontsize))
                _an_node.set_height('0.35')
                if _m.sex == 'M' or _m.sex == 'm':
                    _an_node.set_shape('box')
                elif _m.sex == 'F' or _m.sex == 'f':
                    _an_node.set_shape('ellipse')
                else:
                    pass
                g.add_node(_an_node)
                # Add the edges to the parent nodes, if any.
                if str(_m.sireID) != str(pedobj.kw['missing_parent']):
                    if gname:
                        if garrow:
                            g.add_edge(pydot.Edge(str(pedobj.pedigree[int(_m.sireID)-1].name), str(_m.name)))
                        else:
                            g.add_edge(pydot.Edge(str(pedobj.pedigree[int(_m.sireID)-1].name), str(_m.name), dir='none'))
                    else:
                        if garrow:
                            g.add_edge(pydot.Edge(str(pedobj.pedigree[int(_m.sireID)-1].originalID), str(_m.originalID)))
                        else:
                            g.add_edge(pydot.Edge(str(pedobj.pedigree[int(_m.sireID)-1].originalID), str(_m.originalID), dir='none'))
                if str(_m.damID) != str(pedobj.kw['missing_parent']):
                    if gname:
                        if garrow:
                            g.add_edge(pydot.Edge(str(pedobj.pedigree[int(_m.damID)-1].name), str(_m.name)))
                        else:
                            g.add_edge(pydot.Edge(str(pedobj.pedigree[int(_m.damID)-1].name), str(_m.name), dir='none'))
                    else:
                        if garrow:
                            g.add_edge(pydot.Edge(str(pedobj.pedigree[int(_m.damID)-1].originalID), str(_m.originalID)))
                        else:
                            g.add_edge(pydot.Edge(str(pedobj.pedigree[int(_m.damID)-1].originalID), str(_m.originalID), dir='none'))
    # Or test the new subgraph clusters
    elif gclusters:
        for _g in pedobj.metadata.unique_gen_list:
            _sg_anims = []
            _sg_name = 'sg%s' % (_g)
            if gshowall:
                sg = pydot.Cluster(graph_name=str(_sg_name), suppress_disconnected=False, simplify=True)
            else:
                sg = pydot.Cluster(graph_name=str(_sg_name), suppress_disconnected=True, simplify=True)
            for _m in pedobj.pedigree:
                if int(_m.gen) == int(_g):
                    _sg_anims.append(_m.animalID)
                    # Add a node for the current animal and set some properties.
                    if str(_m.animalID) != str(pedobj.kw['missing_parent']):
                        if gname:
                            _node_name = _m.name
                        else:
                            _node_name = str(_m.animalID)
                        _an_node = pydot.Node(str(_node_name))
                        _an_node.set_fontname('Helvetica')
                        _an_node.set_fontsize(gfontsize)
                        _an_node.set_height('0.35')
                        if _m.sex == 'M' or _m.sex == 'm':
                            _an_node.set_shape('box')
                        if _m.sex == 'F' or _m.sex == 'f':
                            _an_node.set_shape('ellipse')
                        sg.add_node(_an_node)
            g.add_subgraph(sg)
        # Now that we've added the clusters to the graph, define the
        # edges.
        for _m in pedobj.pedigree:
            if str(_m.sireID) != str(pedobj.kw['missing_parent']):
                if gname:
                    if garrow:
                        g.add_edge(pydot.Edge(str(pedobj.pedigree[int(_m.sireID)-1].name), str(_m.name)))
                    else:
                        g.add_edge(pydot.Edge(str(pedobj.pedigree[int(_m.sireID)-1].name), str(_m.name), dir='none'))
                else:
                    if garrow:
                        g.add_edge(pydot.Edge(str(pedobj.pedigree[int(_m.sireID)-1].animalID), str(_m.animalID)))
                    else:
                        g.add_edge(pydot.Edge(str(pedobj.pedigree[int(_m.sireID)-1].animalID), str(_m.animalID), dir='none'))
            if str(_m.damID) != str(pedobj.kw['missing_parent']):
                if gname:
                    if garrow:
                        g.add_edge(pydot.Edge(str(pedobj.pedigree[int(_m.damID)-1].name), str(_m.name)))
                    else:
                        g.add_edge(pydot.Edge(str(pedobj.pedigree[int(_m.damID)-1].name), str(_m.name), dir='none'))
                else:
                    if garrow:
                        g.add_edge(pydot.Edge(str(pedobj.pedigree[int(_m.damID)-1].animalID), str(_m.animalID)))
                    else:
                        g.add_edge(pydot.Edge(str(pedobj.pedigree[int(_m.damID)-1].animalID), str(_m.animalID), dir='none'))
    # Otherwise we can draw a nice graph.
    else:
        for _g in pedobj.metadata.unique_gen_list:
            _sg_anims = []
            _sg_name = 'sg%s' % (_g)
            if gshowall:
                sg = pydot.Subgraph(graph_name=str(_sg_name), suppress_disconnected=False, simplify=True, rank='same')
            else:
                sg = pydot.Subgraph(graph_name=str(_sg_name), suppress_disconnected=True, simplify=True, rank='same')
            for _m in pedobj.pedigree:
                if str(_m.animalID) != str(pedobj.kw['missing_parent']):
                    if int(_m.gen) == int(_g):
                        _sg_anims.append(_m.animalID)
                        ## ->
                        # Add a node for the current animal and set some properties.
                        if gname:
                            _node_name = _m.name
                        else:
                            _node_name = str(_m.animalID)
                        _an_node = pydot.Node(str(_node_name))
                        _an_node.set_fontname('Helvetica')
                        _an_node.set_fontsize(str(gfontsize))
                        _an_node.set_height('0.35')
                        if _m.sex == 'M' or _m.sex == 'm':
                            _an_node.set_shape('box')
                        if _m.sex == 'F' or _m.sex == 'f':
                            _an_node.set_shape('ellipse')
                        sg.add_node(_an_node)
                        ## <-
                        # Add the edges to the parent nodes, if any.
                        if str(_m.sireID) != str(pedobj.kw['missing_parent']):
                            if gname:
                                if garrow:
                                    sg.add_edge(pydot.Edge(str(pedobj.pedigree[int(_m.sireID)-1].name), str(_m.name)))
                                else:
                                    sg.add_edge(pydot.Edge(str(pedobj.pedigree[int(_m.sireID)-1].name), str(_m.name), dir='none'))
                            else:
                                if garrow:
                                    sg.add_edge(pydot.Edge(str(pedobj.pedigree[int(_m.sireID)-1].animalID), str(_m.animalID)))
                                else:
                                    sg.add_edge(pydot.Edge(str(pedobj.pedigree[int(_m.sireID)-1].animalID), str(_m.animalID), dir='none'))
                        if str(_m.damID) != str(pedobj.kw['missing_parent']):
                            if gname:
                                if garrow:
                                    sg.add_edge(pydot.Edge(str(pedobj.pedigree[int(_m.damID)-1].name), str(_m.name)))
                                else:
                                    sg.add_edge(pydot.Edge(str(pedobj.pedigree[int(_m.damID)-1].name), str(_m.name), dir='none'))
                            else:
                                if garrow:
                                    sg.add_edge(pydot.Edge(str(pedobj.pedigree[int(_m.damID)-1].animalID), str(_m.animalID)))
                                else:
                                    sg.add_edge(pydot.Edge(str(pedobj.pedigree[int(_m.damID)-1].animalID), str(_m.animalID), dir='none'))
                        ## <-
            if len(_sg_anims) > 0:
                _sg_list = ''
                for _a in _sg_anims:
                    if len(_sg_list) == 0:
                        _sg_list = '%s' % (_a)
                    else:
                        _sg_list = '%s,%s' % (_sg_list,_a)
            sg.set_rank(_sg_list)
            g.add_subgraph(sg)
            #try:
                #print sg.get_node_list()
            #except:
                #print 'Could not get node list for subgraph!'
            #try:
                #print sg.get_edge_list()
            #except:
                #print 'Could not get edge list for subgraph!'

    # For large graphs it is nice to write out the .dot file so that it does
    # not have to be recreated whenever new_draw_pedigree is called.
    # Especially when I am debugging.
    if gdot:
        dfn = '%s.dot' % (gfilename)
        #try:
        g.write(dfn)
        #except:
        #    if pedobj.kw['messages'] == 'verbose':
        #        print '[ERROR]: pyp_graphics/draw_pedigree() was unable to write the dotfile %s.' % (dfn)
        #    logging.error('pyp_graphics/draw_pedigree() was unable to draw the dotfile %s.', (dfn))

    # Write the graph to an output file.
    #try:
    outfile = '%s.%s' % (gfilename,gformat)
    g.write(outfile, prog='dot', format=gformat)
Beispiel #7
0
def new_draw_colored_pedigree(pedobj, shading, gfilename='pedigree', \
    gtitle='', gformat='jpg', gsize='f', gdot=1, gorient='p', gdirec='', \
    gname=0, garrow=1, gtitloc='b', gtitjust='c', gshowall=1, gprog='dot', \
    ghatch='hatch'):
    """
    draw_pedigree() uses the pydot bindings to the graphviz library -- if they
    are available on your system -- to produce a directed graph of your pedigree
    with paths of inheritance as edges and animals as nodes.  If there is more than
    one generation in the pedigree as determind by the "gen" attributes of the animals
    in the pedigree, draw_pedigree() will use subgraphs to try and group animals in the
    same generation together in the drawing.
    """

    try:
        import pygraphviz
    except ImportError:
        if pedobj.kw['messages'] == 'verbose':
            print '[ERROR]: pyp_graphics/new_draw_pedigree() was unable to import the pygraphviz module!'
        logging.error('pyp_graphics/new_draw_pedigree() was unable to import the pygraphviz module!')
        return 0

    # Maps the 0/1 flags taken by the function and maps them to Python
    # True/False for settine edge and node attributes.
    _tf = {0:False, 1:True}

    from pyp_utils import string_to_table_name
    _gtitle = string_to_table_name(gtitle)

    if gtitloc not in ['t','b']:
        gtitloc = 'b'
    if gtitjust not in ['c','l','r']:
        gtitjust = 'c'

    if not pedobj.kw['pedigree_is_renumbered']:
        if pedobj.kw['messages'] != 'quiet':
            print '[GRAPH]: The pedigree that you passed to pyp_graphics/draw_pedigree() is not renumbered. Because of this, there may be errors in the rendered pedigree. In order to insure that the pedigree drawing is accurate, you should renumber the pedigree before calling draw_pedigree().'
        logging.error('The pedigree that you passed to pyp_graphics/draw_pedigree() is not renumbered. Because of this, there may be errors in the rendered pedigree. In order to insure that the pedigree drawing is accurate, you should renumber the pedigree before calling draw_pedigree().')

    # Create an empty pygraphviz graph using the Agraph class.
    g = pygraphviz.AGraph(directed=True,strict=False)

    # I'm not sure if I need to have this here or not.
    g.graph_attr['type'] = 'graph'

    # Name the graph -- _gtitle has the characters removed which would cause
    # dotfile processing to break.
    g.graph_attr['name'] = _gtitle

    # Set some properties for the graph.  The label attribute is based on the gtitle.
    # In cases where an empty string, e.g. '', is provided as the gtitle dot engine
    # processing breaks.  In such cases, don't add a label.

    if gtitle != '':
        g.graph_attr['label'] = gtitle
        g.graph_attr['labelloc'] = gtitloc
        g.graph_attr['labeljust'] = gtitjust

    # Set the page paper size and writeable area.
    g.graph_attr['page'] = '8.5,11'
    g.graph_attr['size'] = '7.5,10'

    # Set the page orientation.
    if gorient == 'l':
        g.graph_attr['orientation'] = 'landscape'
    else:
        g.graph_attr['orientation'] = 'portrait'

    if gsize != 'l':
        g.graph_attr['ratio'] = 'auto'
    if gdirec == 'RL':
        g.graph_attr['rankdir'] = 'RL'
    elif gdirec == 'LR':
        g.graph_attr['rankdir'] = 'LR'
    else:
        pass

    # Set a few other graph properties.
    g.graph_attr['center'] = 'True'
    g.graph_attr['concentrate'] = 'True'
    g.graph_attr['fontsize'] = str(pedobj.kw['default_fontsize'])
    g.graph_attr['ordering'] = 'out'

    # We need this for coloring the pedigree
    colormin = min(shading.values())
    colormax = max(shading.values())
    color_map = {}

    for _m in pedobj.pedigree:
        # Add a node for the current animal and set some node properties.
        if gname:
            _node_name = _m.name
        else:
            _node_name = _m.animalID
        g.add_node(_node_name)
        n = g.get_node(_node_name)
        n.attr['shape'] = 'box'
        n.attr['fontname'] = 'Helvetica'
        n.attr['fontsize'] = str(pedobj.kw['default_fontsize'])
        n.attr['height'] = '0.35'
        #print '[DEBUG]: sex = ', _m.sex
        if _m.sex == 'M' or _m.sex == 'm':
            n.attr['shape'] = 'box'
        elif _m.sex == 'F' or _m.sex == 'f':
            n.attr['shape'] = 'ellipse'
        else:
            n.attr['shape'] = 'octagon'
            #pass

        # Color the nodes
        if _m.userField == ghatch:
            n.attr['style'] = 'filled,peripheries=2'
        else:
            n.attr['style'] = 'filled'
            _color = get_color_32(shading[_m.animalID], colormin, colormax)
            n.attr['fillcolor'] = _color
            # Add values to the color map
            if not color_map.has_key(shading[_m.animalID]):
                color_map[shading[_m.animalID]] = _color

        # Add the edges to the parent nodes, if any.
        if _m.sireID != pedobj.kw['missing_parent']:
            if gname:
                _sire_edge = pedobj.pedigree[int(_m.sireID)-1].name
            else:
                # Check some outputs -- should I be using the animalID or the
                # originalID to assign edges? Nodes are based on the animalID,
                # so edges should also be in order to maintain consistency.
                #_sire_edge = pedobj.pedigree[int(_m.sireID)-1].originalID
                _sire_edge = pedobj.pedigree[int(_m.sireID)-1].animalID
            g.add_edge(_sire_edge,_node_name)
            if not _tf[garrow]:
                e = g.get_edge(_sire_edge,_anim_node)
                e.attr['dir'] = 'none'
        if _m.damID != pedobj.kw['missing_parent']:
            if gname:
                _dam_edge = pedobj.pedigree[int(_m.damID)-1].name
            else:
                _dam_edge = pedobj.pedigree[int(_m.damID)-1].animalID
            g.add_edge(_dam_edge,_node_name)
            if not _tf[garrow]:
                e = g.get_edge(_dam_edge,_anim_node)
                e.attr['dir'] = 'none'

    # For large graphs it is nice to write out the .dot file so that it does
    # not have to be recreated whenever new_draw_pedigree is called.
    # Especially when I am debugging.
    if gdot:
        dfn = '%s.dot' % (gfilename)
        try:
            g.write(dfn)
        except:
            if pedobj.kw['messages'] == 'verbose':
                print '[ERROR]: pyp_graphics/new_draw_pedigree() was unable to write the dotfile %s.' % (dfn)
            logging.error('pyp_graphics/new_draw_pedigree() was unable to draw the dotfile %s.', (dfn))


    # Write the color map to a file.
    #try:
    mapfile = '%s_color_map.txt' % (gfilename)
    mf = file(mapfile,'w')
    mf.write('# Color map data\n')
    mf.write('# Data are metric (number of sons/descendants/etc.) followed\n')
    mf.write('# by color in RGB.\n')
    for k,v in color_map.iteritems():
        line = '%s\t%s\n' % (k,v)
        mf.write(line)
    mf.close()
    #except:
        #outfile = '%s_color_map.txt' % (gfilename)
        #if pedobj.kw['messages'] == 'verbose':
            #print '[ERROR]: pyp_jbc/new_draw_colored_pedigree() was unable to write the color map %s.' % (outfile)
        #logging.error('pyp_jbc/new_draw_colored_pedigree() was unable to write the color map %s.', (outfile))
        #return 0

    # Write the graph to an output file.
    #try:
    outfile = '%s.%s' % (gfilename,gformat)
    g.draw(outfile,prog=gprog)
    return 1
Beispiel #8
0
def draw_colored_pedigree(pedobj, shading, gfilename='pedigree', gtitle='My_Pedigree', gformat='jpg', gsize='f', gdot='1', gorient='l', gdirec='', gname=0, gfontsize=10, garrow=1, gtitloc='b', gtitjust='c', ghatch='hatch', gprog='dot'):
    """
    draw_colored_pedigree() uses the pydot bindings to the graphviz library to produce a
    directed graph of your pedigree with paths of inheritance as edges and animals as
    nodes.  If there is more than one generation in the pedigree as determind by the "gen"
    attributes of the animals in the pedigree, draw_pedigree() will use subgraphs to try
    and group animals in the same generation together in the drawing.  Nodes will be
    colored based on the number of outgoing connections (number of offspring).
    """
    from pyp_utils import string_to_table_name
    _gtitle = string_to_table_name(gtitle)

    if gtitloc not in ['t','b']:
        gtitloc = 'b'
    if gtitjust not in ['c','l','r']:
        gtitjust = 'c'

    print '[DEBUG]: Entered draw_colored_pedigree()'

#     try:
    import pydot

    # Build a list of generations -- if we have more than on, we can use the
    # "rank=same" option in dot to get nicer output.
    gens = pedobj.metadata.unique_gen_list
    # Set some properties for the graph.
    g = pydot.Dot(label=gtitle, labelloc=gtitloc, labeljust=gtitjust, graph_name=_gtitle, type='graph', strict=False, suppress_disconnected=True, simplify=True)

    # Make sure that gfontsize has a valid value.
    try:
        gfontsize = int(gfontsize)
    except:
        gfontsize = 10
    if gfontsize < 10:
        gfontsize = 10
    gfontsize = str(gfontsize)
#     print 'gfontsize = %s' % (gfontsize)
    g.set_page("8.5,11")
    g.set_size("7.5,10")
    if gorient == 'l':
        g.set_orientation("landscape")
    else:
        g.set_orientation("portrait")
    if gsize != 'l':
        g.set_ratio("auto")
    if gdirec == 'RL':
        g.set_rankdir('RL')
    elif gdirec == 'LR':
        g.set_rankdir('LR')
    else:
        pass
    g.set_center('true')
    g.set_concentrate('true')
    g.set_ordering('out')
    if gformat not in g.formats:
        gformat = 'jpg'
    # If we do not have any generations, we have to draw a less-nice graph.
    colormin = min(shading.values())
    colormax = max(shading.values())
    color_map = {}
    if len(gens) <= 1:
        animalCounter = 0
        print '\t[DEBUG]: Only one generation'
        for _m in pedobj.pedigree:
            animalCounter = animalCounter + 1
            if numpy.fmod(animalCounter,pedobj.kw['counter']) == 0:
                print '\t[DEBUG]: Records read: %s ' % ( animalCounter )
            # Add a node for the current animal and set some properties.
            if gname:
                _node_name = _m.name
            else:
                _node_name = _m.animalID
            _an_node = pydot.Node(_node_name)
            _an_node.set_fontname('Helvetica')
            # _an_node.set_fontsize('10')
            _an_node.set_fontsize(gfontsize)
            _an_node.set_height('0.35')
            if _m.sex == 'M' or _m.sex == 'm':
                _an_node.set_shape('box')
            elif _m.sex == 'F' or _m.sex == 'f':
                _an_node.set_shape('ellipse')
            else:
                pass
            #print _m.userField, ghatch, ( _m.userField == ghatch )
            if _m.userField == ghatch:
                _an_node.set_style('filled,peripheries=2')
            else:
                _an_node.set_style('filled')
            try:
                _color = color_map[shading[_m.animalID]]
            except KeyError:
                _color = get_color_32(shading[_m.animalID], colormin, colormax)
                color_map[shading[_m.animalID]] = _color
                print '\t[DEBUG]: %s added to cache' % ( _color )
            _an_node.set_fillcolor(_color)
            g.add_node(_an_node)
            # Add the edges to the parent nodes, if any.
            if _m.sireID != pedobj.kw['missing_parent']:
                if gname:
                    if garrow:
                        g.add_edge(pydot.Edge(pedobj.pedigree[int(_m.sireID)-1].name, _m.name))
                    else:
                        g.add_edge(pydot.Edge(pedobj.pedigree[int(_m.sireID)-1].name, _m.name, dir='none'))
                else:
                    if garrow:
                        g.add_edge(pydot.Edge(pedobj.pedigree[int(_m.sireID)-1].originalID,_m.originalID))
                    else:
                        g.add_edge(pydot.Edge(pedobj.pedigree[int(_m.sireID)-1].originalID,_m.originalID, dir='none'))
            if _m.damID != pedobj.kw['missing_parent']:
                if gname:
                    if garrow:
                        g.add_edge(pydot.Edge(pedobj.pedigree[int(_m.damID)-1].name, _m.name))
                    else:
                        g.add_edge(pydot.Edge(pedobj.pedigree[int(_m.damID)-1].name, _m.name, dir='none'))
                else:
                    if garrow:
                        g.add_edge(pydot.Edge(pedobj.pedigree[int(_m.damID)-1].originalID,_m.originalID))
                    else:
                        g.add_edge(pydot.Edge(pedobj.pedigree[int(_m.damID)-1].originalID,_m.originalID, dir='none'))
    # Otherwise we can draw a nice graph.
    else:
        for _g in gens:
            print '\t[DEBUG]: Looping over generations'
            _sg_anims = []
            _sg_name = 'sg%s' % (_g)
            sg = pydot.Subgraph(graph_name=_sg_name, suppress_disconnected=True, simplify=True)
            sg.set_simplify(True)
            animalCounter = 0
            for _m in pedobj.pedigree:
                animalCounter = animalCounter + 1
                if numpy.fmod(animalCounter,pedobj.kw['counter']) == 0:
                    print '\t[DEBUG]: Records read: %s ' % ( animalCounter )
                if int(_m.gen) == int(_g):
                    _sg_anims.append(_m.animalID)
                # Add a node for the current animal and set some properties.
                if gname:
                    _node_name = _m.name
                else:
                    _node_name = _m.animalID
                _an_node = pydot.Node(_node_name)
                _an_node.set_fontname('Helvetica')
                _an_node.set_fontsize(gfontsize)
                _an_node.set_height('0.35')
                if _m.sex == 'M' or _m.sex == 'm':
                    _an_node.set_shape('box')
                elif _m.sex == 'F' or _m.sex == 'f':
                    _an_node.set_shape('ellipse')
                else:
                    pass
                if _m.userField == ghatch:
                    _an_node.set_style('filled,peripheries=2')
                else:
                    _an_node.set_style('filled')
                _color = get_color_32(shading[_m.animalID], colormin, colormax)
                _an_node.set_fillcolor(_color)
                sg.add_node(_an_node)
                # Add the edges to the parent nodes, if any.
                if _m.sireID != pedobj.kw['missing_parent']:
                    if gname:
                        if garrow:
                            sg.add_edge(pydot.Edge(pedobj.pedigree[int(_m.sireID)-1].name,_m.name))
                        else:
                            sg.add_edge(pydot.Edge(pedobj.pedigree[int(_m.sireID)-1].name,_m.name, dir='none'))
                    else:
                        if garrow:
                            sg.add_edge(pydot.Edge(pedobj.pedigree[int(_m.sireID)-1].originalID,_m.originalID))
                        else:
                            sg.add_edge(pydot.Edge(pedobj.pedigree[int(_m.sireID)-1].originalID,_m.originalID, dir='none'))
                #if int(_m.damID) != 0:
                if _m.damID != pedobj.kw['missing_parent']:
                    if gname:
                        if garrow:
                            sg.add_edge(pydot.Edge(pedobj.pedigree[int(_m.damID)-1].name,_m.name))
                        else:
                            sg.add_edge(pydot.Edge(pedobj.pedigree[int(_m.damID)-1].name,_m.name, dir='none'))
                    else:
                        if garrow:
                            sg.add_edge(pydot.Edge(pedobj.pedigree[int(_m.damID)-1].originalID,_m.originalID))
                        else:
                            sg.add_edge(pydot.Edge(pedobj.pedigree[int(_m.damID)-1].originalID,_m.originalID, dir='none'))
            if len(_sg_anims) > 0:
                _sg_list = ''
                for _a in _sg_anims:
                    if len(_sg_list) == 0:
                        _sg_list = 'same,%s' % (_a)
                    else:
                        _sg_list = '%s,%s' % (_sg_list,_a)
            sg.set_rank(_sg_list)
            g.add_subgraph(sg)
    # For large graphs it is nice to write out the .dot file so that it does not have to be recreated
    # whenever draw_pedigree is called.  Especially when I am debugging.  :-)
    if gdot:
        dfn = '%s.dot' % (gfilename)
#             try:
        g.write(dfn)
#             except:
#                 pass
    # Write the graph to an output file.
    outfile = '%s.%s' % (gfilename,gformat)
    if gprog not in ['dot','neato','none']:
        gprog = 'dot'
    if gprog != 'none':
        g.write(outfile,prog=gprog,format=gformat)
    return 1