Source code for rnaglib.drawing.rna_layout

import numpy as np
import networkx as nx
import matplotlib.pyplot as plt

[docs]def rescale_layout(pos, scale=1): """ Return scaled position array to (-scale, scale) in all axes. The function acts on NumPy arrays which hold position information. Each position is one row of the array. The dimension of the space equals the number of columns. Each coordinate in one column. To rescale, the mean (center) is subtracted from each axis separately. Then all values are scaled so that the largest magnitude value from all axes equals `scale` (thus, the aspect ratio is preserved). The resulting NumPy Array is returned (order of rows unchanged). Parameters ---------- pos : numpy array positions to be scaled. Each row is a position. scale : number (default: 1) The size of the resulting extent in all directions. Returns ------- pos : numpy array scaled positions. Each row is a position. """ # Find max length over all dimensions lim = 0 # max coordinate for all axes for i in range(pos.shape[1]): pos[:, i] -= pos[:, i].mean() lim = max(abs(pos[:, i]).max(), lim) # rescale to (-scale, scale) in all directions, preserves aspect if lim > 0: for i in range(pos.shape[1]): pos[:, i] *= scale / lim return pos
def _process_params(G, center, dim): # Some boilerplate code. import numpy as np if not isinstance(G, nx.Graph): empty_graph = nx.Graph() empty_graph.add_nodes_from(G) G = empty_graph if center is None: center = np.zeros(dim) else: center = np.asarray(center) if len(center) != dim: msg = "length of center coordinates must match dimension of layout" raise ValueError(msg) return G, center
[docs]def circular_layout(G, scale=1, center=None, dim=2): # dim=2 only """ Position nodes on a circle. Parameters ---------- G : NetworkX graph or list of nodes A position will be assigned to every node in G. scale : number (default: 1) Scale factor for positions. center : array-like or None Coordinate pair around which to center the layout. dim : int Dimension of layout. If dim>2, the remaining dimensions are set to zero in the returned positions. Returns ------- pos : dict A dictionary of positions keyed by node Examples -------- >>> G = nx.path_graph(4) >>> pos = nx.circular_layout(G) Notes ----- This algorithm currently only works in two dimensions and does not try to minimize edge crossings. """ import numpy as np G, center = _process_params(G, center, dim) paddims = max(0, (dim - 2)) if len(G) == 0: pos = {} elif len(G) == 1: pos = {nx.utils.arbitrary_element(G): center} else: # Discard the extra angle since it matches 0 radians. theta = np.linspace(0, 1, len(G) + 1)[:-1] * 2 * np.pi theta = theta.astype(np.float32) pos = np.column_stack([np.cos(theta), np.sin(theta), np.zeros((len(G), paddims))]) pos = rescale_layout(pos, scale=scale) + center try: sorted_n = sorted(G, key=lambda x: x.split(".")[2], reverse=True) except: sorted_n = sorted(G) pos = dict(zip(sorted_n, pos)) return pos
if __name__ == "__main__": G = nx.Graph() G.add_nodes_from([('A', 2), ('A', 3), ('A', 1), ('A', 5)]) G.add_edges_from([(('A', 2), ('A', 5))]) pos = circular_layout(G) nx.draw_networkx(G, pos)