def draw(morphology, synapses=None, neuron_node_id=None): """Draw dendrogram with synapses. Args: morphology (Neurite|Morphology): a Morphology instance of NeuroM package. synapses (DataFrame): synapses dataframe. neuron_node_id (int|None): node id of ``morphology``. If None then it is taken from ``synapses[TARGET_NODE_ID]``. Returns: plotly.graph_objects.Figure: plotly figure Example .. literalinclude:: ../../../examples/dendrogram.py :pyobject: plain_example """ assert (is_integer_dtype(synapses[TARGET_NODE_ID].dtype) and is_integer_dtype(synapses[SOURCE_NODE_ID].dtype) and is_integer_dtype(synapses[POST_SECTION_ID].dtype) and is_integer_dtype(synapses[PRE_SECTION_ID].dtype)), \ 'Section ids and nodes columns of `synapses` arg must be integers' dendrogram = SynDendrogram(morphology) positions = layout_dendrogram(dendrogram, np.array([0, 0])) w, h = get_size(positions) positions = move_positions(positions, np.array([.5 * w, 0])) if not synapses.empty: if neuron_node_id is None: neuron_node_id = _get_default_neuron_node_id(synapses) _position_synapses(positions, synapses, neuron_node_id) synapses['synapse_id'] = synapses.index.values # convert 'target node' to string for discrete colormap synapses = synapses.astype({TARGET_NODE_ID: str}) fig = px.scatter(synapses, x='x', y='y', color=TARGET_NODE_ID, color_discrete_map=_get_synapse_colormap(synapses), hover_data=synapses.columns) else: fig = graph_objects.Figure() fig.update_xaxes(range=[-.05 * w, 1.05 * w], zeroline=False) fig.update_yaxes(range=[-.05 * h, 1.05 * h], zeroline=False) shapes = _get_draw_shapes(dendrogram, positions) fig.update_layout(shapes=shapes) _add_neurite_legend(fig, dendrogram) return fig
def test_layout_dendrogram(): def assert_layout(dendrogram): for i, child in enumerate(dendrogram.children): # child is higher than parent in Y coordinate assert (positions[child][1] >= positions[dendrogram][1] + dendrogram.height) if i < len(dendrogram.children) - 1: next_child = dendrogram.children[i + 1] # X space between child is enough for their widths assert (positions[next_child][0] - positions[child][0] > .5 * (next_child.width + child.width)) assert_layout(child) neuron = load_neuron(NEURON_PATH) dendrogram = dm.Dendrogram(neuron) positions = dm.layout_dendrogram(dendrogram, np.array([0, 0])) assert_layout(dendrogram)
def draw(neuron, synapses=None, neuron_node_id=None): """Draw dendrogram with synapses. Args: neuron (Neurite|Neuron): a Neurite or a Neuron instance of NeuroM package. synapses (DataFrame): synapses dataframe. neuron_node_id (int|None): node id of ``neuron``. If None then it is taken from ``synapses[TARGET_NODE_ID]``. Returns: plotly.graph_objects.Figure: plotly figure """ synapses = synapses.astype({ '@target_node': int, '@source_node': int, 'afferent_section_id': int, 'efferent_section_id': int }) dendrogram = SynDendrogram(neuron) positions = layout_dendrogram(dendrogram, np.array([0, 0])) w, h = get_size(positions) positions = move_positions(positions, np.array([.5 * w, 0])) if not synapses.empty: if neuron_node_id is None: neuron_node_id = _get_default_neuron_node_id(synapses) _position_synapses(positions, synapses, neuron_node_id) synapses['synapse_id'] = synapses.index.values # convert 'target node' to string for discrete colormap synapses = synapses.astype({TARGET_NODE_ID: str}) fig = px.scatter(synapses, x='x', y='y', color=TARGET_NODE_ID, color_discrete_map=_get_synapse_colormap(synapses), hover_data=synapses.columns) else: fig = graph_objects.Figure() fig.update_xaxes(range=[-.05 * w, 1.05 * w], zeroline=False) fig.update_yaxes(range=[-.05 * h, 1.05 * h], zeroline=False) shapes = _get_draw_shapes(dendrogram, positions) fig.update_layout(shapes=shapes) _add_neurite_legend(fig, dendrogram) return fig
def plot_dendrogram(ax, obj, show_diameters=True): """Plots Dendrogram of `obj`. Args: ax: matplotlib axes obj (neurom.Neuron, neurom.Tree): neuron or tree show_diameters (bool): whether to show node diameters or not """ dendrogram = Dendrogram(obj) positions = layout_dendrogram(dendrogram, np.array([0, 0])) w, h = get_size(positions) positions = move_positions(positions, np.array([.5 * w, 0])) ax.set_xlim([-.05 * w, 1.05 * w]) ax.set_ylim([-.05 * h, 1.05 * h]) ax.set_title('Morphology Dendrogram') ax.set_xlabel('micrometers (um)') ax.set_ylabel('micrometers (um)') shapes = _get_dendrogram_shapes(dendrogram, positions, show_diameters) ax.add_collection(PatchCollection(shapes, match_original=True)) ax.set_aspect('auto') ax.legend(handles=_get_dendrogram_legend(dendrogram))