Smartview (web graphics)

Explorer

Web server to explore trees interactively.

The main endpoints are for the static files to serve the frontend (that uses javascript), and for exposing an api to manipulate the trees in the backend.

add_tree(tree, name=None, layouts=None, extra_style=None)[source]

Add tree, layouts, etc to the global variables, and return its name.

add_trees_from_request()[source]

Add trees to the global var g_trees and return a dict of {name: id}.

callback(tree_id)[source]

Remove a tree.

explore(tree, name=None, layouts=None, host='127.0.0.1', port=None, verbose=False, compress=None, keep_server=False, open_browser=True, **kwargs)[source]

Run the web server, add tree and open a browser to visualize it.

Return the appropriate node search function according to the command.

get_drawing_kwargs(tree_id, args)[source]

Return the drawing arguments initialized as specified in the args.

Return a function of a node that evaluates the given expression.

get_newick(tree_id, max_mb)[source]

Return the newick representation of the given tree.

get_next_available_port(host='127.0.0.1', port_min=5000, port_max=6000)[source]

Return the next available port where we can put a server socket.

get_search_function(text)[source]

Return a function of a node that returns True for the searched nodes.

get_tid(tree_id)[source]

Return the tree id and the subtree id, with the appropriate types.

Return a function of a node that sees if it matches the given pattern.

get_trees_from_file(filename, fileobject=None)[source]

Return list of {‘name’: …, ‘newick’: …} extracted from file.

get_trees_from_form()[source]

Return list of dicts with tree info read from a form in the request.

get_trees_from_nexus_or_newick(btext, name_newick)[source]

Return list of {‘name’: …, ‘newick’: …} extracted from btext.

json_error(error)[source]
load_tree(tree_id)[source]

Add tree to g_trees and initialize it if not there, and return it.

loads(tree_text, parser)[source]

Return tree loaded from the text using the given parser.

make_name()[source]

Return a unique tree name like ‘tree-<number>’.

nice_html(content, title='Tree Explorer')[source]

Return the content as part of a nice-looking html page.

open_browser_window(host='127.0.0.1', port=5000)[source]

Try to open a browser window in a different process.

remove_tree(name)[source]

Remove all global references to the tree.

req_json()[source]

Return what request.json would return, but gracefully aborting.

safer_eval(code, context)[source]

Return a safer version of eval(code, context).

sort(tree_id, node_id, key_text, reverse)[source]

Sort the (sub)tree corresponding to tree_id and node_id.

start_server(host='127.0.0.1', port=None, verbose=False, keep_server=False)[source]

Create a thread running the web server and return it and the server.

stop_server()[source]

Stop the running server.

Store the results and parents of a search and return their numbers.

Layout

Definition of the basic elements for a tree representation (Layout and Decoration), extra labels (Label), and the default tree style.

The valid keys for a tree style are:

  • shape

  • radius

  • angle-start

  • angle-end

  • angle-span

  • node-height-min

  • content-height-min

  • collapsed

  • show-popup-props

  • hide-popup-props

  • is-leaf-fn

  • box

  • dot

  • hz-line

  • vt-line

  • aliases

Some properties will be used directly by the backend: shape, node-height-min, content-height-min, radius, angle-start, angle-end, angle-span, show-popup-props, hide-popup-props, is-leaf-fn.

Others will be controlled by the css class of the element in the frontend: box, dot, hz-line, vt-line.

And the “aliases” part will tell the frontend which styles are referenced.

Example of a tree style in use:

my_tree_style = {
    'shape': 'circular',  # or 'rectangular'
    'radius': 5,
    'angle-start': -180,
    'angle-end': 180,  # alternatively we can give 'angle-span'
    'node-height-min': 10,
    'content-height-min': 5,
    'collapsed': {'shape': 'outline', 'fill-opacity': 0.8},
    'show-popup-props': None,  # all defined properties
    'hide-popup-props': ['support'],  # except support
    'is-leaf-fn': lambda node: node.level > 4,
    'box': {'fill': 'green', 'opacity': 0.1, 'stroke': 'blue'},
    'dot': {'shape': 'hexagon', 'fill': 'red'},
    'hz-line': {'stroke-width': 2},
    'vt-line': {'stroke': '#ffff00'},
    'aliases': {
        'support': {'fill': 'green'},  # changes the default one
        'my-leaf': {'fill': 'blue', 'font-weight': 'bold'},
    },
}

layout = Layout(name='Example layout', draw_tree=my_tree_style)
class Decoration(face, position='top', column=0, anchor=None)[source]

A decoration is a face with a position (“top”, “bottom”, “right”, etc.), a column (an integer used for relative order with other faces in the same position), and an anchor point (to fine-tune the position of things like texts within them).

__init__(face, position='top', column=0, anchor=None)[source]
anchor: tuple
column: int
face: Face
position: str
class Label(code, style, node_type, position, column, anchor, fs_max)
anchor

Alias for field number 5

code

Alias for field number 0

column

Alias for field number 4

fs_max

Alias for field number 6

node_type

Alias for field number 2

position

Alias for field number 3

style

Alias for field number 1

class Layout(name, draw_tree=None, draw_node=None, cache_size=None, active=True)[source]

A complete specification of how to represent a tree.

Layouts have a name and two functions providing the style and decorations of the full tree and the visible nodes.

When exploring a tree, layouts compose. Using several layouts will add extra graphic representations, and/or overwrite some styles from previous layouts.

__init__(name, draw_tree=None, draw_node=None, cache_size=None, active=True)[source]
Parameters:
  • name – String identifying the layout (to select in the gui, etc.)

  • draw_tree – Function specifying tree style and decorations.

  • draw_node – Function specifying node style and decorations.

  • cache_size – Number of elements that draw_node() will memorize (useful values are None for infinite cache, and 0 for no cache).

  • active – If True, the layout is used immediately when exploring.

property draw_node
property draw_tree
default_draw_node(node, collapsed)[source]
to_elements(xs)[source]

Return a list of the elements of iterable xs as Decorations/dicts.

update_style(style, style_new)[source]

Update the style dictionary merging properly with style_new.

Faces

A “face” is a piece of drawn information.

Different faces can represent different kinds of information in different forms. Faces have a drawing function that returns the graphic elements that will show the information, and the size they occupy (in tree coordinates).

They know how to represent node(s) information, confined to an area of a given size. They do it with a method face.draw(nodes, size, …) which returns the graphic elements and the actual size they use (which may be smaller than the allocated size).

The sizes are always given in “tree units”. The size in pixels is always that size multiplied by the zoom.

class BoxFace(wmax, hmax=None, style='', text=None)[source]

A box (with optionally a text inside).

__init__(wmax, hmax=None, style='', text=None)[source]

Save all the parameters that we may want to use.

class BoxedFace(wmax, hmax=None, text=None)[source]

A shape defined by a box (with optionally a text inside).

__init__(wmax, hmax=None, text=None)[source]

Save all the parameters that we may want to use.

draw(nodes, size, collapsed, zoom=(1, 1), ax_ay=(0, 0), r=1)[source]

Return a list of graphic elements and the actual size they use.

The retuned graphic elements normally depend on the node(s). They have to fit inside the given size (dx, dy) in tree coordinates (dx==0 means no limit for dx).

If collapsed=[], nodes contain only one node (and is not collapsed). Otherwise, nodes (== collapsed) is a list of the collapsed nodes.

The zoom is passed in case the face wants to represent things differently according to its size on the screen.

ax_ay is the anchor point within the box of the given size (from 0 for left/up, to 1 for right/down).

r * size[1] * zoom[1] is the size in pixels of the left border, whether we are in rectangular or circular mode.

class CircleFace(rmax=None, style='')[source]

A circle.

__init__(rmax=None, style='')[source]

Save all the parameters that we may want to use.

draw(nodes, size, collapsed, zoom=(1, 1), ax_ay=(0, 0), r=1)[source]

Return a list of graphic elements and the actual size they use.

The retuned graphic elements normally depend on the node(s). They have to fit inside the given size (dx, dy) in tree coordinates (dx==0 means no limit for dx).

If collapsed=[], nodes contain only one node (and is not collapsed). Otherwise, nodes (== collapsed) is a list of the collapsed nodes.

The zoom is passed in case the face wants to represent things differently according to its size on the screen.

ax_ay is the anchor point within the box of the given size (from 0 for left/up, to 1 for right/down).

r * size[1] * zoom[1] is the size in pixels of the left border, whether we are in rectangular or circular mode.

class EvalTextFace(expression, fs_min=2, fs_max=16, rotation=0, style='')[source]

A text that results from evaluating an expression on the node.

The style can be a string which refers to the style the gui is going to assign it, or a dictionary with svg attributes for text.

__init__(expression, fs_min=2, fs_max=16, rotation=0, style='')[source]

Save all the parameters that we may want to use.

draw(nodes, size, collapsed, zoom=(1, 1), ax_ay=(0, 0), r=1)[source]

Return a list of graphic elements and the actual size they use.

The retuned graphic elements normally depend on the node(s). They have to fit inside the given size (dx, dy) in tree coordinates (dx==0 means no limit for dx).

If collapsed=[], nodes contain only one node (and is not collapsed). Otherwise, nodes (== collapsed) is a list of the collapsed nodes.

The zoom is passed in case the face wants to represent things differently according to its size on the screen.

ax_ay is the anchor point within the box of the given size (from 0 for left/up, to 1 for right/down).

r * size[1] * zoom[1] is the size in pixels of the left border, whether we are in rectangular or circular mode.

class Face[source]

Base class (mostly an example of the expected interface).

__init__()[source]

Save all the parameters that we may want to use.

draw(nodes, size, collapsed, zoom=(1, 1), ax_ay=(0, 0), r=1)[source]

Return a list of graphic elements and the actual size they use.

The retuned graphic elements normally depend on the node(s). They have to fit inside the given size (dx, dy) in tree coordinates (dx==0 means no limit for dx).

If collapsed=[], nodes contain only one node (and is not collapsed). Otherwise, nodes (== collapsed) is a list of the collapsed nodes.

The zoom is passed in case the face wants to represent things differently according to its size on the screen.

ax_ay is the anchor point within the box of the given size (from 0 for left/up, to 1 for right/down).

r * size[1] * zoom[1] is the size in pixels of the left border, whether we are in rectangular or circular mode.

class ImageFace(path, wmax, hmax=None, style='', text=None)[source]

An image (with optionally a text inside).

__init__(path, wmax, hmax=None, style='', text=None)[source]

Save all the parameters that we may want to use.

class LegendFace(title, variable, colormap=None, value_range=None, color_range=None)[source]

A legend with information about the data we are visualizing.

__init__(title, variable, colormap=None, value_range=None, color_range=None)[source]

Save all the parameters that we may want to use.

class PolygonFace(rmax=None, shape=3, style='')[source]

A polygon.

__init__(rmax=None, shape=3, style='')[source]

Save all the parameters that we may want to use.

draw(nodes, size, collapsed, zoom=(1, 1), ax_ay=(0, 0), r=1)[source]

Return a list of graphic elements and the actual size they use.

The retuned graphic elements normally depend on the node(s). They have to fit inside the given size (dx, dy) in tree coordinates (dx==0 means no limit for dx).

If collapsed=[], nodes contain only one node (and is not collapsed). Otherwise, nodes (== collapsed) is a list of the collapsed nodes.

The zoom is passed in case the face wants to represent things differently according to its size on the screen.

ax_ay is the anchor point within the box of the given size (from 0 for left/up, to 1 for right/down).

r * size[1] * zoom[1] is the size in pixels of the left border, whether we are in rectangular or circular mode.

class PropFace(prop, fmt='%s', fs_min=2, fs_max=16, rotation=0, style='')[source]

A text showing the given property, and optionally a special format.

__init__(prop, fmt='%s', fs_min=2, fs_max=16, rotation=0, style='')[source]

Save all the parameters that we may want to use.

class RectFace(wmax, hmax=None, style='', text=None)[source]

A rectangle (with optionally a text inside).

__init__(wmax, hmax=None, style='', text=None)[source]

Save all the parameters that we may want to use.

class SeqFace(seq, seqtype='aa', poswidth=15, draw_text=True, hmax=None, fs_max=15, style='', render='auto')[source]

A sequence of nucleotides or amino acids.

__init__(seq, seqtype='aa', poswidth=15, draw_text=True, hmax=None, fs_max=15, style='', render='auto')[source]

Save all the parameters that we may want to use.

draw(nodes, size, collapsed, zoom, ax_ay, r)[source]

Return a list of graphic elements and the actual size they use.

The retuned graphic elements normally depend on the node(s). They have to fit inside the given size (dx, dy) in tree coordinates (dx==0 means no limit for dx).

If collapsed=[], nodes contain only one node (and is not collapsed). Otherwise, nodes (== collapsed) is a list of the collapsed nodes.

The zoom is passed in case the face wants to represent things differently according to its size on the screen.

ax_ay is the anchor point within the box of the given size (from 0 for left/up, to 1 for right/down).

r * size[1] * zoom[1] is the size in pixels of the left border, whether we are in rectangular or circular mode.

class TextFace(text, fs_min=2, fs_max=16, rotation=0, style='')[source]

A fixed text.

__init__(text, fs_min=2, fs_max=16, rotation=0, style='')[source]

Save all the parameters that we may want to use.

draw_texts(box, ax_ay, texts, fs_max, rotation, style)[source]

Yield texts so they fit in the box.

eval_as_str(code, node)[source]

Return the given code evaluated on values related to the given node.

first_value(tree, code=None)[source]

Return value of evaluating the given code, on the first possible node.

make_nodes_summary(nodes, code=None)[source]

Return values summarizing the nodes, and if all are accounted for.

safer_eval(code, context)[source]

Return a safer version of eval(code, context).

text_repr(texts, all_have)[source]

Return a summarized representation of the given texts.

texts_size(texts, size_max, fs_max, zoom, shrink_x=True, r=1)[source]

Return the (dx, dy) dimensions of the texts so they fit in size_max.

Graphics

Basic graphical commands.

They are all lists whose first element is a string saying which kind of element it is (like “line”), and the rest are its parameters.

They are sent as json to the javascript viewer, which interprets them (in draw.js) and draws the corresponding graphics.

Whenever a box is used, it is in “tree coordinates” (that is, not multiplied by the zoom or the radius, so not in pixels).

are_valid_angles(*angles)[source]
draw_arc(p1, p2, style='')[source]
draw_array(box, a)[source]
draw_box(box, style='')[source]
draw_circle(center, radius=1, style='')[source]
draw_group(elements, circular, shift)[source]

Yield the given drawing elements with their coordinates shifted.

draw_header(text, fs_max=None, rotation=0, style='')[source]
draw_hz_line(p1, p2, parent_of=None, style='')[source]
draw_image(box, href, style='')[source]
draw_legend(title, variable, colormap=None, value_range=None, color_range=None)[source]
draw_line(p1, p2, style='')[source]
draw_nodebox(box, name='', props=None, node_id=None, result_of=None, style='')[source]
draw_nodedot(point, dy_max, style='')[source]
draw_outline(box)[source]
draw_polygon(center, radius, shape=3, style='')[source]
draw_rect(box, style='')[source]
draw_seq(box, seq, seqtype='aa', draw_text=True, fs_max=None, style='', render='auto')[source]
draw_skeleton(points)[source]
draw_text(box, anchor, text, fs_max=None, rotation=0, style='')[source]
draw_vt_line(p1, p2, style='')[source]
set_panel(panel=0)[source]
set_xmaxs(xmaxs)[source]

Coordinates

class Box(x, y, dx, dy)
dx

Alias for field number 2

dy

Alias for field number 3

x

Alias for field number 0

y

Alias for field number 1

class Size(dx, dy)
dx

Alias for field number 0

dy

Alias for field number 1

get_xs(box)[source]
get_ys(box)[source]
make_box(point, size)[source]