Skip to content

ragraph.plot.components

Plot components.

This module contains several re-usable plot components that contain the data for a Plotly (sub-) figure. See Component for the definition of a plot component.

Blank

Blank(style: Style = Style())

Bases: Component

Blank plot component.

Parameters:

Name Type Description Default
style Style

Plot style mapping.

Style()
Source code in ragraph/plot/components/blank.py
def __init__(self, style: Style = Style()):
    trace = go.Scatter(
        x=[0.5 * style.xstep],
        y=[0.5 * style.ystep],
        mode="markers",
        marker=dict(
            line=dict(
                color="#FFFFFF",
            ),
            color="#FFFFFF",
        ),
        showlegend=False,
        hoverinfo="skip",
    )

    xaxis = go.layout.XAxis(
        automargin=False,
        autorange=False,
        scaleanchor="y",
        scaleratio=1.0,
        range=(0, 1),
        showticklabels=False,
    )
    yaxis = go.layout.YAxis(
        automargin=False,
        autorange=False,
        showticklabels=False,
        range=(0, 1),
    )

    super().__init__(
        width=style.xstep * style.boxsize,
        height=style.ystep * style.boxsize,
        traces=[trace],
        xaxis=xaxis,
        yaxis=yaxis,
    )

Labels

Labels(leafs: List[Node], style: Style = Style())

Bases: Component

Labels list plot component.

Parameters:

Name Type Description Default
leafs List[Node]

List of leaf nodes.

required
style Style

Plot style mapping.

Style()
Source code in ragraph/plot/components/labels.py
def __init__(self, leafs: List[Node], style: Style = Style()):
    labels = [node.name for node in leafs]
    if style.labels.shorten is True:
        short_labels = [label.split(".")[-1] for label in labels]
    elif style.labels.shorten:
        short_labels = [style.labels.shorten(label) for label in labels]
    else:
        short_labels = labels

    label_length = max([len(label) for label in short_labels], default=0)
    fontsize = (
        int(0.6 * style.boxsize) if style.labels.fontsize is None else style.labels.fontsize
    )

    if style.labels.textorientation == "vertical":
        height = (
            label_length * fontsize * style.labels.fontaspectratio + 0.3 * style.boxsize
        )  # Text width plus 0.3 boxsize as margin.

        num = len(leafs)
        xmax = num * style.xstep
        width = xmax * style.boxsize

        xdata = [(i + 0.5) * style.xstep for i in range(num)]
        ydata = num * [-0.5 * height / style.boxsize]

        annotations = [
            dict(
                x=x,
                y=y,
                text=text,
                showarrow=False,
                yshift=0,
                textangle=-90,
                yanchor="bottom",
                font=dict(
                    color=style.labels.fontcolor,
                    family=style.labels.fontfamily,
                    size=fontsize,
                ),
            )
            for x, y, text in zip(xdata, ydata, short_labels)
        ]

        xaxis, yaxis = deepcopy(style.labels.xaxis), deepcopy(style.labels.yaxis)
        xaxis.update(range=[0, num])
        yaxis.update(
            range=[-0.5 * height / style.boxsize, 0.5 * height / style.boxsize],
            scaleanchor="x",
            scaleratio=1.0,
        )
    else:
        # Default option.
        width = (
            label_length * fontsize * style.labels.fontaspectratio + 0.5 * style.boxsize
        )  # Text width plus 0.3 boxsize as margin.

        num = len(leafs)
        ymax = num * style.ystep
        height = ymax * style.boxsize

        xdata = num * [0.5 * width / style.boxsize]
        ydata = [ymax - (i + 0.5) * style.ystep for i in range(num)]

        annotations = [
            dict(
                x=x,
                y=y,
                text=text,
                showarrow=False,
                yshift=0,
                textangle=0,
                xanchor="right",
                font=dict(
                    color=style.labels.fontcolor,
                    family=style.labels.fontfamily,
                    size=fontsize,
                ),
            )
            for x, y, text in zip(xdata, ydata, short_labels)
        ]

        xaxis, yaxis = deepcopy(style.labels.xaxis), deepcopy(style.labels.yaxis)
        xaxis.update(
            range=[-0.5 * width / style.boxsize, 0.5 * width / style.boxsize],
            scaleanchor="y",
            scaleratio=1.0,
        )
        yaxis.update(range=[0, num])

    super().__init__(
        width=width,
        height=height,
        traces=[],
        annotations=annotations,
        shapes=None,
        xaxis=xaxis,
        yaxis=yaxis,
    )

Legend

Legend(edges: List[Edge], style: Style = Style())

Bases: Component

Legend component.

Parameters:

Name Type Description Default
edges List[Edge]

List displayed edges.

required
style Style

Plot style mapping.

Style()
Source code in ragraph/plot/components/legend.py
def __init__(self, edges: List[Edge], style: Style = Style()):
    if style.piemap.display in ["kinds", "labels", "weight labels"]:
        # create categorical legend:
        categories = style.piemap.fields or get_legend_categories(
            edges=edges, display=style.piemap.display
        )

        max_label_length = max(len(cat) for cat in categories) if categories else 0
        fontsize = (
            int(0.6 * style.boxsize) if style.legend.fontsize is None else style.legend.fontsize
        )
        width = (
            max_label_length * fontsize * style.legend.fontaspectratio + 1 * style.boxsize
        )  # Text width plus 2 box sizes as margin.

        traces = get_categorical_legend_traces(categories=categories, style=style)
        xaxis, yaxis = deepcopy(style.legend.xaxis), deepcopy(style.legend.yaxis)
        num = len(categories)
        xaxis.update(
            range=[0, (width / style.boxsize) * style.xstep],
        )
        yaxis.update(
            range=[0, (num + 1) * style.ystep],
        )

        super().__init__(
            width=width,
            height=num * style.ystep * style.boxsize,
            traces=traces,
            shapes=None,
            xaxis=xaxis,
            yaxis=yaxis,
        )

    elif style.piemap.display == "weights":
        # Create numerical legend.
        traces = get_numerical_legend_traces(edges=edges, style=style)
        xaxis, yaxis = deepcopy(style.legend.xaxis), deepcopy(style.legend.yaxis)

        weight_labels = style.piemap.fields or get_legend_categories(
            edges=edges, display="weight labels"
        )

        max_label_length = max(len(label) for label in weight_labels) if weight_labels else 0

        fontsize = (
            int(0.6 * style.boxsize) if style.legend.fontsize is None else style.legend.fontsize
        )

        width = 2.5 * style.xstep * len(weight_labels) * style.boxsize
        xaxis.update(
            range=[0, width / style.boxsize * style.xstep],
            scaleanchor="y",
            scaleratio=1.0,
        )
        yaxis.update(range=[0, (style.legend.height) * style.ystep])

        super().__init__(
            width=width,
            height=(style.legend.height) * style.boxsize,
            traces=traces,
            shapes=None,
            xaxis=xaxis,
            yaxis=yaxis,
        )

PieMap

1
2
3
4
5
6
7
PieMap(
    rows: List[Node],
    cols: List[Node],
    edges: List[Edge] = [],
    style: Style = Style(),
    **kwargs
)

Bases: Component

A map of piecharts plot component.

This map, or matrix, of pie-charts display the edges between leaf nodes.

Parameters:

Name Type Description Default
rows List[Node]

The nodes to be placed on the rows of the matrix.

required
cols List[Node]

The columns to be placed on the columns of the matrix.

required
edges List[Edge]

Edges to be displayed between leaf nodes.

[]
style Style

Plot style option mapping.

Style()
Note

The pie-charts can represent a number of things, including edge weights, edge labels as well as other metrics. The node hierarchy is included using squares drawn around the diagonal.

Furthermore, bus nodes have their respective row and column in a shaded background color. This sets apart the buses' "highly integrative" edges from the regular edges between nodes.

Source code in ragraph/plot/components/piemap.py
def __init__(
    self,
    rows: List[Node],
    cols: List[Node],
    edges: List[Edge] = [],
    style: Style = Style(),
    **kwargs,
):
    # Custom grid.
    grid_shapes = _get_grid_shapes(rows, cols, style)

    # Display data
    pie_traces, pie_shapes = _get_pies_data(rows, cols, edges, style)

    hierarchy_shapes, kind_shapes = [], []
    if rows == cols:
        # Matrix is symmetric.
        # Shapes to indicate hierarchy.
        hierarchy_shapes = _get_hierarchy_shapes(rows, style)

        # Divide different node kinds by special lines.
        kind_shapes = _get_kind_shapes(rows, style)

    highlight_shapes = _get_highlight_shapes(rows, cols, style)

    # Combine all traces and shapes.
    traces = pie_traces
    shapes = highlight_shapes + grid_shapes + pie_shapes + kind_shapes + hierarchy_shapes

    dim = (len(rows), len(cols))
    xaxis, yaxis = deepcopy(style.piemap.xaxis), deepcopy(style.piemap.yaxis)
    xaxis.update(range=[0, dim[1]], scaleanchor="y", scaleratio=1.0)
    yaxis.update(range=[0, dim[0]])

    super().__init__(
        width=dim[1] * style.boxsize,
        height=dim[0] * style.boxsize,
        traces=traces,
        shapes=shapes,
        xaxis=xaxis,
        yaxis=yaxis,
    )

Tree

Tree(leafs: List[Node], style: Style = Style())

Bases: Component

Hierarchy tree plot component of leaf nodes up to their roots.

Leaf nodes are plotted as a vertical list with their roots on the left side.

Parameters:

Name Type Description Default
leafs List[Node]

List of leaf nodes.

required
style Style

Plot style mapping.

Style()
Source code in ragraph/plot/components/tree.py
def __init__(self, leafs: List[Node], style: Style = Style()):
    ancestors, depth, xdict, ydict = _get_data(leafs=leafs, style=style)

    node_trace = _get_node_trace(
        xdict=xdict,
        ydict=ydict,
        style=style,
    )
    line_shapes = _get_line_shapes(ancestors=ancestors, xdict=xdict, ydict=ydict, style=style)

    # Calculating geometric boundaries.
    width = (depth + 1) * style.xstep * style.boxsize
    height = len(leafs) * style.ystep * style.boxsize

    xaxis, yaxis = deepcopy(style.tree.xaxis), deepcopy(style.tree.yaxis)
    xaxis.update(range=(-0.5, width / style.boxsize - 0.5), scaleanchor="y", scaleratio=1.0)
    yaxis.update(range=(0, height / style.boxsize))

    super().__init__(
        width=width,
        height=height,
        traces=[node_trace],
        shapes=line_shapes,
        xaxis=xaxis,
        yaxis=yaxis,
    )

blank

Blank plot component

Blank

Blank(style: Style = Style())

Bases: Component

Blank plot component.

Parameters:

Name Type Description Default
style Style

Plot style mapping.

Style()
Source code in ragraph/plot/components/blank.py
def __init__(self, style: Style = Style()):
    trace = go.Scatter(
        x=[0.5 * style.xstep],
        y=[0.5 * style.ystep],
        mode="markers",
        marker=dict(
            line=dict(
                color="#FFFFFF",
            ),
            color="#FFFFFF",
        ),
        showlegend=False,
        hoverinfo="skip",
    )

    xaxis = go.layout.XAxis(
        automargin=False,
        autorange=False,
        scaleanchor="y",
        scaleratio=1.0,
        range=(0, 1),
        showticklabels=False,
    )
    yaxis = go.layout.YAxis(
        automargin=False,
        autorange=False,
        showticklabels=False,
        range=(0, 1),
    )

    super().__init__(
        width=style.xstep * style.boxsize,
        height=style.ystep * style.boxsize,
        traces=[trace],
        xaxis=xaxis,
        yaxis=yaxis,
    )

chord

Chord plots usings openchord

chord

1
2
3
4
5
6
7
8
chord(
    graph: Graph,
    nodes: Optional[Union[List[Node], List[str]]] = None,
    style: Optional[Style] = None,
    adj_kwargs: Optional[Dict[str, Any]] = None,
    symmetrize: bool = False,
    show: bool = False,
) -> Chord

Make a chord plot for the given nodes in a graph.

Parameters:

Name Type Description Default
graph Graph

Graph to create a chord plot for.

required
nodes Optional[Union[List[Node], List[str]]]

Nodes or node names to include in the chord plot. Defaults to leaf nodes.

None
style Optional[Style]

Plotting style.

None
adj_kwargs Optional[Dict[str, Any]] None
symmetrize bool

Whether to symmetrize the adjacency matrix.

False
show bool

Whether to show the resulting figure.

False

Returns:

Type Description
Chord

Chord plot using openchord.

Source code in ragraph/plot/components/chord.py
def chord(
    graph: Graph,
    nodes: Optional[Union[List[Node], List[str]]] = None,
    style: Optional[Style] = None,
    adj_kwargs: Optional[Dict[str, Any]] = None,
    symmetrize: bool = False,
    show: bool = False,
) -> ocd.Chord:
    """Make a chord plot for the given nodes in a graph.

    Arguments:
        graph: Graph to create a chord plot for.
        nodes: Nodes or node names to include in the chord plot. Defaults to leaf nodes.
        style: Plotting style.
        adj_kwargs: Additional arguments to [`ragraph.graph.Graph.get_adjacency_matrix`
            ][ragraph.graph.Graph.get_adjacency_matrix].
        symmetrize: Whether to symmetrize the adjacency matrix.
        show: Whether to show the resulting figure.

    Returns:
        Chord plot using openchord.
    """
    nodes = graph.leafs if nodes is None else nodes
    nodes = [n if isinstance(n, Node) else graph.node_dict[n] for n in nodes]
    labels = [n.name for n in nodes]

    adj_kwargs = dict() if adj_kwargs is None else adj_kwargs
    adj = graph.get_adjacency_matrix(nodes=nodes, **adj_kwargs)

    if symmetrize:
        dim = len(nodes)
        for row in range(dim):
            for col in range(row, dim):
                value = (adj[row][col] + adj[col][row]) / 2
                adj[row][col] = value
                adj[col][row] = value

    style: Style = Style() if style is None else style
    cs = style.chord
    fig = ocd.Chord(adj, labels, radius=cs.radius)
    fig.padding = (
        cs.fontsize * cs.fontfactor * max(len(x) for x in labels)
        if cs.padding is None
        else cs.padding
    )
    fig.gap_size = cs.gap_size
    fig.ribbon_gap = cs.ribbon_gap
    fig.ribbon_stiffness = cs.ribbon_stiffness
    fig.arc_thickness = cs.arc_thickness
    fig.bg_color = cs.bg_color
    fig.bg_transparency = cs.bg_transparency
    fig.font_size = cs.fontsize
    fig.font_family = cs.fontfamily

    fig.colormap = style.palettes.categorical

    if show:
        return fig.show()
    else:
        return fig

labels

Labels list plot component

Labels

Labels(leafs: List[Node], style: Style = Style())

Bases: Component

Labels list plot component.

Parameters:

Name Type Description Default
leafs List[Node]

List of leaf nodes.

required
style Style

Plot style mapping.

Style()
Source code in ragraph/plot/components/labels.py
def __init__(self, leafs: List[Node], style: Style = Style()):
    labels = [node.name for node in leafs]
    if style.labels.shorten is True:
        short_labels = [label.split(".")[-1] for label in labels]
    elif style.labels.shorten:
        short_labels = [style.labels.shorten(label) for label in labels]
    else:
        short_labels = labels

    label_length = max([len(label) for label in short_labels], default=0)
    fontsize = (
        int(0.6 * style.boxsize) if style.labels.fontsize is None else style.labels.fontsize
    )

    if style.labels.textorientation == "vertical":
        height = (
            label_length * fontsize * style.labels.fontaspectratio + 0.3 * style.boxsize
        )  # Text width plus 0.3 boxsize as margin.

        num = len(leafs)
        xmax = num * style.xstep
        width = xmax * style.boxsize

        xdata = [(i + 0.5) * style.xstep for i in range(num)]
        ydata = num * [-0.5 * height / style.boxsize]

        annotations = [
            dict(
                x=x,
                y=y,
                text=text,
                showarrow=False,
                yshift=0,
                textangle=-90,
                yanchor="bottom",
                font=dict(
                    color=style.labels.fontcolor,
                    family=style.labels.fontfamily,
                    size=fontsize,
                ),
            )
            for x, y, text in zip(xdata, ydata, short_labels)
        ]

        xaxis, yaxis = deepcopy(style.labels.xaxis), deepcopy(style.labels.yaxis)
        xaxis.update(range=[0, num])
        yaxis.update(
            range=[-0.5 * height / style.boxsize, 0.5 * height / style.boxsize],
            scaleanchor="x",
            scaleratio=1.0,
        )
    else:
        # Default option.
        width = (
            label_length * fontsize * style.labels.fontaspectratio + 0.5 * style.boxsize
        )  # Text width plus 0.3 boxsize as margin.

        num = len(leafs)
        ymax = num * style.ystep
        height = ymax * style.boxsize

        xdata = num * [0.5 * width / style.boxsize]
        ydata = [ymax - (i + 0.5) * style.ystep for i in range(num)]

        annotations = [
            dict(
                x=x,
                y=y,
                text=text,
                showarrow=False,
                yshift=0,
                textangle=0,
                xanchor="right",
                font=dict(
                    color=style.labels.fontcolor,
                    family=style.labels.fontfamily,
                    size=fontsize,
                ),
            )
            for x, y, text in zip(xdata, ydata, short_labels)
        ]

        xaxis, yaxis = deepcopy(style.labels.xaxis), deepcopy(style.labels.yaxis)
        xaxis.update(
            range=[-0.5 * width / style.boxsize, 0.5 * width / style.boxsize],
            scaleanchor="y",
            scaleratio=1.0,
        )
        yaxis.update(range=[0, num])

    super().__init__(
        width=width,
        height=height,
        traces=[],
        annotations=annotations,
        shapes=None,
        xaxis=xaxis,
        yaxis=yaxis,
    )

legend

Legend plot component

Legend

Legend(edges: List[Edge], style: Style = Style())

Bases: Component

Legend component.

Parameters:

Name Type Description Default
edges List[Edge]

List displayed edges.

required
style Style

Plot style mapping.

Style()
Source code in ragraph/plot/components/legend.py
def __init__(self, edges: List[Edge], style: Style = Style()):
    if style.piemap.display in ["kinds", "labels", "weight labels"]:
        # create categorical legend:
        categories = style.piemap.fields or get_legend_categories(
            edges=edges, display=style.piemap.display
        )

        max_label_length = max(len(cat) for cat in categories) if categories else 0
        fontsize = (
            int(0.6 * style.boxsize) if style.legend.fontsize is None else style.legend.fontsize
        )
        width = (
            max_label_length * fontsize * style.legend.fontaspectratio + 1 * style.boxsize
        )  # Text width plus 2 box sizes as margin.

        traces = get_categorical_legend_traces(categories=categories, style=style)
        xaxis, yaxis = deepcopy(style.legend.xaxis), deepcopy(style.legend.yaxis)
        num = len(categories)
        xaxis.update(
            range=[0, (width / style.boxsize) * style.xstep],
        )
        yaxis.update(
            range=[0, (num + 1) * style.ystep],
        )

        super().__init__(
            width=width,
            height=num * style.ystep * style.boxsize,
            traces=traces,
            shapes=None,
            xaxis=xaxis,
            yaxis=yaxis,
        )

    elif style.piemap.display == "weights":
        # Create numerical legend.
        traces = get_numerical_legend_traces(edges=edges, style=style)
        xaxis, yaxis = deepcopy(style.legend.xaxis), deepcopy(style.legend.yaxis)

        weight_labels = style.piemap.fields or get_legend_categories(
            edges=edges, display="weight labels"
        )

        max_label_length = max(len(label) for label in weight_labels) if weight_labels else 0

        fontsize = (
            int(0.6 * style.boxsize) if style.legend.fontsize is None else style.legend.fontsize
        )

        width = 2.5 * style.xstep * len(weight_labels) * style.boxsize
        xaxis.update(
            range=[0, width / style.boxsize * style.xstep],
            scaleanchor="y",
            scaleratio=1.0,
        )
        yaxis.update(range=[0, (style.legend.height) * style.ystep])

        super().__init__(
            width=width,
            height=(style.legend.height) * style.boxsize,
            traces=traces,
            shapes=None,
            xaxis=xaxis,
            yaxis=yaxis,
        )

get_categorical_legend_traces

1
2
3
get_categorical_legend_traces(
    categories: List[str], style: Style = Style()
) -> List[Scatter]

Create categorical legend traces.

Parameters:

Name Type Description Default
categories List[str]

List of categories.

required
style Style

Plot style mapping.

Style()

Returns:

Type Description
List[Scatter]

List of traces.

Source code in ragraph/plot/components/legend.py
def get_categorical_legend_traces(
    categories: List[str], style: Style = Style()
) -> List[go.Scatter]:
    """Create categorical legend traces.

    Arguments:
        categories: List of categories.
        style: Plot style mapping.

    Returns:
        List of traces.
    """
    traces = []
    x0 = 0.5
    y0 = (len(categories) - 0.5) * style.ystep

    xdata = []
    ydata = []

    fontsize = int(0.6 * style.boxsize) if style.legend.fontsize is None else style.legend.fontsize

    for idx, cat in enumerate(categories):
        y = y0 - idx * style.ystep
        color = style.palettes.get_categorical_color(idx, field=cat)
        traces.append(
            go.Scatter(
                x=[x0],
                y=[y],
                text=[cat],
                mode="markers",
                marker=dict(color=color),
                hoverinfo="text",
                showlegend=False,
            )
        )

        xdata.append(x0 + 0.5 * style.xstep)
        ydata.append(y)

    traces.append(
        go.Scatter(
            x=xdata,
            y=ydata,
            text=categories,
            hoverinfo="text",
            mode="text",
            showlegend=False,
            textfont=dict(
                color=style.legend.fontcolor,
                family=style.legend.fontfamily,
                size=fontsize,
            ),
            textposition="middle right",
        )
    )

    return traces

get_legend_categories

1
2
3
get_legend_categories(
    edges: List[Edge], display: str
) -> List[str]

Get the number of categories to be included in the legend.

Parameters:

Name Type Description Default
edges List[Edge]

The list of edges that are being displayed.

required
display str

The selected display mode.

required

Returns:

Type Description
List[str]

list of categories.

Source code in ragraph/plot/components/legend.py
def get_legend_categories(edges: List[Edge], display: str) -> List[str]:
    """Get the number of categories to be included in the legend.

    Arguments:
        edges: The list of edges that are being displayed.
        display: The selected display mode.

    Returns:
        list of categories.
    """
    if display == "kinds":
        return sorted(list(set([e.kind for e in edges])))
    elif display == "labels":
        labels = set()
        for e in edges:
            labels.update(set(e.labels))
        return sorted(list(labels))
    elif display == "weight labels":
        weight_labels = set()
        for e in edges:
            weight_labels.update(set([w for w in e.weights]))
        return sorted(list(weight_labels))
    else:
        return []

get_numerical_legend_traces

1
2
3
get_numerical_legend_traces(
    edges: List[Edge], style: Style = Style()
) -> List[Scatter]

Get traces for a numerical legend,

Parameters:

Name Type Description Default
edges List[Edge]

List of edges that are displayed.

required
style Style

Style object.

Style()

Returns:

Type Description
List[Scatter]

List of traces.

Source code in ragraph/plot/components/legend.py
def get_numerical_legend_traces(edges: List[Edge], style: Style = Style()) -> List[go.Scatter]:
    """Get traces for a numerical legend,

    Arguments:
        edges: List of edges that are displayed.
        style: Style object.

    Returns:
       List of traces.
    """
    weight_labels = style.piemap.fields or get_legend_categories(
        edges=edges, display="weight labels"
    )

    traces = []
    for idx, label in enumerate(weight_labels):
        colors = style.palettes.get_continuous_palette(label)
        edge_dict = defaultdict(list)
        for e in edges:
            if e.weights.get(label, None):
                edge_dict[e.source, e.target].append(e.weights[label])

        values = [sum(weights) for weights in edge_dict.values()]
        min_value = min(values, default=0)
        max_value = max(values, default=0)
        if min_value == max_value:
            min_value = max_value - 1

        traces.extend(
            get_swatchtraces(
                idx=idx,
                name=label,
                colors=colors,
                min_value=min_value,
                max_value=max_value,
                style=style,
            )
        )

    return traces

get_swatchtraces

1
2
3
4
5
6
7
8
get_swatchtraces(
    idx: int,
    name: str,
    colors: List[str],
    min_value: float,
    max_value: float,
    style: Style = Style(),
) -> List[Scatter]

Swatch bar of color map.

Parameters:

Name Type Description Default
idx int

Number of the swatch that must be created.

required
name str

name of the swatch trace.

required
colors List[str]

List of colors to be added to the swatch trace

required
min_value float

Minimum value of the weight related to the color map.

required
max_value float

Maximmum value of the weight related to the color map.

required
style Style

Style object.

Style()

Returns:

Type Description
List[Scatter]

List of go.Scatter traces.

Source code in ragraph/plot/components/legend.py
def get_swatchtraces(
    idx: int,
    name: str,
    colors: List[str],
    min_value: float,
    max_value: float,
    style: Style = Style(),
) -> List[go.Scatter]:
    """Swatch bar of color map.

    Arguments:
        idx: Number of the swatch that must be created.
        name: name of the swatch trace.
        colors: List of colors to be added to the swatch trace
        min_value: Minimum value of the weight related to the color map.
        max_value: Maximmum value of the weight related to the color map.
        style: Style object.

    Returns:
        List of go.Scatter traces.
    """
    if style.legend.n_ticks < 2:
        x = (1.8 * idx + 0.75) * style.xstep
    else:
        x = (2.5 * idx + 0.75) * style.xstep

    ystep = style.legend.height * style.ystep / len(colors)
    traces = []

    for idc, color in enumerate(colors):
        x0 = x - 0.35 * style.xstep
        x1 = x + 0.35 * style.xstep
        xdata = [x0, x0, x1, x1]

        y0 = style.ystep + (idc) * ystep
        y1 = style.ystep + (idc + 1) * ystep
        ydata = [y0, y1, y1, y0]

        traces.append(
            go.Scatter(
                x=xdata,
                y=ydata,
                fill="toself",
                text=[name for x in xdata],
                mode="lines",
                hoverinfo="text",
                marker=dict(size=0),
                fillcolor=color,
                line=dict(color=color),
                showlegend=False,
            )
        )

    fontsize = int(0.6 * style.boxsize) if style.legend.fontsize is None else style.legend.fontsize

    if style.legend.n_ticks >= 2:
        n = style.legend.n_ticks
        tick_step = (max_value - min_value) / (n - 1)
        traces.append(
            go.Scatter(
                x=[x + 0.5 * style.xstep for step in range(n)],
                y=[style.ystep + step * style.legend.height / (n - 1) for step in range(n)],
                text=["{:.1f}".format(min_value + step * tick_step) for step in range(n)],
                showlegend=False,
                mode="text",
                textfont=dict(
                    color=style.legend.fontcolor,
                    family=style.legend.fontfamily,
                    size=0.7 * fontsize,
                ),
                hoverinfo="text",
                textposition="middle right",
            )
        )

    traces.append(
        go.Scatter(
            x=[x],
            y=[0.5 * style.ystep],
            mode="text",
            text=[name[0:3] + "."],
            showlegend=False,
            textfont=dict(
                color=style.legend.fontcolor,
                family=style.legend.fontfamily,
                size=fontsize,
            ),
            hoverinfo="text",
        )
    )
    return traces

piemap

Piechart mapping matrix plot component

The mapping plot is a matrix of pie-charts, indicating the edges between leaf nodes.

The nodes are identically placed from left-to-right as well as top-to-bottom. This results in a diagonal (from top-left to bottom-right) of 'self loops', which are commonly used to indicate "the nodes themselves".

The pie-charts can represent a number of things, including edge weights, edge labels as well as other metrics. The node hierarchy is included using squares drawn around the diagonal.

Furthermore, bus nodes have their respective row and column in a shaded background color. This sets apart the buses' "highly integrative" edges from the regular edges between nodes.

PieMap

1
2
3
4
5
6
7
PieMap(
    rows: List[Node],
    cols: List[Node],
    edges: List[Edge] = [],
    style: Style = Style(),
    **kwargs
)

Bases: Component

A map of piecharts plot component.

This map, or matrix, of pie-charts display the edges between leaf nodes.

Parameters:

Name Type Description Default
rows List[Node]

The nodes to be placed on the rows of the matrix.

required
cols List[Node]

The columns to be placed on the columns of the matrix.

required
edges List[Edge]

Edges to be displayed between leaf nodes.

[]
style Style

Plot style option mapping.

Style()
Note

The pie-charts can represent a number of things, including edge weights, edge labels as well as other metrics. The node hierarchy is included using squares drawn around the diagonal.

Furthermore, bus nodes have their respective row and column in a shaded background color. This sets apart the buses' "highly integrative" edges from the regular edges between nodes.

Source code in ragraph/plot/components/piemap.py
def __init__(
    self,
    rows: List[Node],
    cols: List[Node],
    edges: List[Edge] = [],
    style: Style = Style(),
    **kwargs,
):
    # Custom grid.
    grid_shapes = _get_grid_shapes(rows, cols, style)

    # Display data
    pie_traces, pie_shapes = _get_pies_data(rows, cols, edges, style)

    hierarchy_shapes, kind_shapes = [], []
    if rows == cols:
        # Matrix is symmetric.
        # Shapes to indicate hierarchy.
        hierarchy_shapes = _get_hierarchy_shapes(rows, style)

        # Divide different node kinds by special lines.
        kind_shapes = _get_kind_shapes(rows, style)

    highlight_shapes = _get_highlight_shapes(rows, cols, style)

    # Combine all traces and shapes.
    traces = pie_traces
    shapes = highlight_shapes + grid_shapes + pie_shapes + kind_shapes + hierarchy_shapes

    dim = (len(rows), len(cols))
    xaxis, yaxis = deepcopy(style.piemap.xaxis), deepcopy(style.piemap.yaxis)
    xaxis.update(range=[0, dim[1]], scaleanchor="y", scaleratio=1.0)
    yaxis.update(range=[0, dim[0]])

    super().__init__(
        width=dim[1] * style.boxsize,
        height=dim[0] * style.boxsize,
        traces=traces,
        shapes=shapes,
        xaxis=xaxis,
        yaxis=yaxis,
    )

tree

Hierarchy tree plot component

This module contains the Tree component which produces a Component for the hierarchy tree of a vertical list of leaf nodes up to their roots which are put on their left.

Tree

Tree(leafs: List[Node], style: Style = Style())

Bases: Component

Hierarchy tree plot component of leaf nodes up to their roots.

Leaf nodes are plotted as a vertical list with their roots on the left side.

Parameters:

Name Type Description Default
leafs List[Node]

List of leaf nodes.

required
style Style

Plot style mapping.

Style()
Source code in ragraph/plot/components/tree.py
def __init__(self, leafs: List[Node], style: Style = Style()):
    ancestors, depth, xdict, ydict = _get_data(leafs=leafs, style=style)

    node_trace = _get_node_trace(
        xdict=xdict,
        ydict=ydict,
        style=style,
    )
    line_shapes = _get_line_shapes(ancestors=ancestors, xdict=xdict, ydict=ydict, style=style)

    # Calculating geometric boundaries.
    width = (depth + 1) * style.xstep * style.boxsize
    height = len(leafs) * style.ystep * style.boxsize

    xaxis, yaxis = deepcopy(style.tree.xaxis), deepcopy(style.tree.yaxis)
    xaxis.update(range=(-0.5, width / style.boxsize - 0.5), scaleanchor="y", scaleratio=1.0)
    yaxis.update(range=(0, height / style.boxsize))

    super().__init__(
        width=width,
        height=height,
        traces=[node_trace],
        shapes=line_shapes,
        xaxis=xaxis,
        yaxis=yaxis,
    )