diff --git a/brian2tools/mdexport/expander.py b/brian2tools/mdexport/expander.py index 75085d43..500ae746 100644 --- a/brian2tools/mdexport/expander.py +++ b/brian2tools/mdexport/expander.py @@ -704,8 +704,9 @@ def expand_initializer(self, initializer): (initializer['index'] != 'True' and initializer['index'] != 'False')): init_str += ' if ' + self.render_expression(initializer['index']) elif (isinstance(initializer['index'], bool) or - (initializer['index'] == 'True' or - initializer['index'] == 'False')): + (isinstance(initializer['index'], str) and + (initializer['index'] == 'True' or + initializer['index'] == 'False'))): if initializer['index'] is True or initializer['index'] == 'True': init_str += '' # "to all members" implied else: @@ -796,10 +797,10 @@ def expand_connector(self, connector): self.expand_identifiers(connector['identifiers'])) return con_str + '.' + endll - - - + + + def expand_pathway(self, pathway): """ Expand `SynapticPathway` @@ -864,7 +865,7 @@ def expand_summed_variables(self, sum_variables): sum_var_str += self.expand_summed_variable(sum_var) return sum_var_str - + def expand_runregularly(self, run_reg): """ @@ -880,4 +881,4 @@ def expand_runregularly(self, run_reg): ' code: ' + self.prepare_math_statements(run_reg['code'], separate=True) + ' will be executed' + endll) - return md_str + return md_str \ No newline at end of file diff --git a/brian2tools/plotting/base.py b/brian2tools/plotting/base.py index 28bb385d..83749c15 100644 --- a/brian2tools/plotting/base.py +++ b/brian2tools/plotting/base.py @@ -106,10 +106,7 @@ def brian_plot(brian_obj, kwds['rate_unit'] = _get_best_unit(smooth_rate) return plot_rate(brian_obj.t, smooth_rate, axes=axes, **kwds) elif isinstance(brian_obj, Morphology): - if kwds: - logger.warn('plot_dendrogram does not take any additional keyword ' - 'arguments, ignoring them.') - return plot_dendrogram(brian_obj, axes=axes) + return plot_dendrogram(brian_obj, axes=axes, **kwds) elif isinstance(brian_obj, Synapses): if len(brian_obj) == 0: raise TypeError('Synapses object does not have any synapses.') diff --git a/brian2tools/plotting/morphology.py b/brian2tools/plotting/morphology.py index 4cf6b5c9..a42f78cf 100644 --- a/brian2tools/plotting/morphology.py +++ b/brian2tools/plotting/morphology.py @@ -34,15 +34,15 @@ def _plot_morphology2D(morpho, axes, colors, color = colors[color_counter % len(colors)] if isinstance(morpho, Soma): - x, y = morpho.x/um, morpho.y/um - radius = morpho.diameter/um/2 + x, y = float(np.squeeze(morpho.x/um)), float(np.squeeze(morpho.y/um)) + radius = float(np.squeeze(morpho.diameter/um/2)) circle = Circle((x, y), radius=radius, color=color) axes.add_patch(circle) - - + + else: coords = morpho.coordinates/um - + if show_diameter: coords_2d = coords[:, :2] directions = np.diff(coords_2d, axis=0) @@ -56,7 +56,7 @@ def _plot_morphology2D(morpho, axes, colors, (coords_2d - orthogonal*radius[:, np.newaxis])[::-1]]) patch = Polygon(points, color=color) axes.add_patch(patch) - + else: axes.plot(coords[:, 0], coords[:, 1], color=color, lw=2) if show_compartments: @@ -74,7 +74,7 @@ def _plot_morphology2D(morpho, axes, colors, show_compartments=show_compartments, show_diameter=show_diameter, colors=colors, color_counter=color_counter+1) - + def _plot_morphology3D(morpho, figure, colors, values, value_norm, value_colormap, show_diameters=True, @@ -352,7 +352,7 @@ def plot_morphology(morphology, plot_3d=None, show_compartments=False, return axes -def plot_dendrogram(morphology, axes=None): +def plot_dendrogram(morphology, axes=None, **kwds): ''' Plot a "dendrogram" of a morphology, i.e. an abstract representation which visualizes the branching structure and the length of each section. @@ -365,6 +365,12 @@ def plot_dendrogram(morphology, axes=None): The `~matplotlib.axes.Axes` instance used for plotting. Defaults to ``None`` which means that a new `~matplotlib.axes.Axes` will be created for the plot. + **kwds + Any additional keyword arguments are passed to matplotlib's + `~matplotlib.axes.Axes.plot`, `~matplotlib.axes.Axes.vlines`, and + `~matplotlib.axes.Axes.hlines` calls. Only arguments accepted by all + three functions should be used (e.g. ``color``, ``alpha``, + ``linewidth``). Returns ------- @@ -424,9 +430,12 @@ def plot_dendrogram(morphology, axes=None): x_values = (np.array(min_index) + np.array(max_index)) / 2.0 + clip_on = kwds.pop('clip_on', False) + lw = kwds.pop('lw', kwds.pop('linewidth', 2)) + # Plot the dendogram with lengths of the vertical lines representing the # total distance to the root - plt.plot(x_values[0], length_metric[0], 'ko', clip_on=False) + plt.plot(x_values[0], length_metric[0], marker='o', clip_on=clip_on, **kwds) for sec, (x, depth) in enumerate(zip(x_values, length_metric)): child_start_idx = (sec+1)*max_children num_children = flat_morpho.morph_children_num[sec+1] @@ -434,9 +443,9 @@ def plot_dendrogram(morphology, axes=None): child_indices = children[child_start_idx:child_start_idx+num_children] child_depth = length_metric[child_indices-1] child_x = x_values[child_indices-1] - axes.vlines(child_x, depth, child_depth, clip_on=False, lw=2) - axes.hlines(depth, min(child_x), max(child_x), lw=2) + axes.vlines(child_x, depth, child_depth, clip_on=clip_on, lw=lw, **kwds) + axes.hlines(depth, min(child_x), max(child_x), lw=lw, **kwds) axes.set_xticks([]) axes.set_ylabel('distance from root (um)') axes.set_xlim(-1, terminal_counter) - return axes + return axes \ No newline at end of file diff --git a/brian2tools/tests/test_baseexport.py b/brian2tools/tests/test_baseexport.py index bc958e75..c0c73598 100644 --- a/brian2tools/tests/test_baseexport.py +++ b/brian2tools/tests/test_baseexport.py @@ -4,6 +4,7 @@ PopulationRateMonitor, EventMonitor, set_device, run, device, Network, Synapses, PoissonInput, TimedArray, Function) +from brian2.core.base import BrianObject from brian2.core.namespace import get_local_namespace from brian2.equations.equations import (DIFFERENTIAL_EQUATION, FLOAT, SUBEXPRESSION, @@ -236,7 +237,7 @@ def test_spikegenerator(): assert spike_gen_dict['indices'] == [0] assert spike_gen_dict['indices'].dtype == int - assert float(spike_gen_dict['times']) == float(time) + assert float(spike_gen_dict['times'][0]) == float(time[0]) assert spike_gen_dict['times'][:].dimensions == second assert spike_gen_dict['times'].dtype == float @@ -898,14 +899,16 @@ def test_ExportDevice_unsupported(): """ start_scope() set_device('exporter') - eqn = ''' - v = 1 :1 - g :1 - ''' - G = NeuronGroup(1, eqn) - _ = PoissonInput(G, 'g', 1, 1 * Hz, 1) - # with pytest.raises(NotImplementedError): - run(10 * ms) + + class UnsupportedObject(BrianObject): + def __init__(self): + super().__init__(name='unsupported*') + + obj = UnsupportedObject() + net = Network(obj) + with pytest.raises(NotImplementedError): + net.run(10 * ms) + device.reinit() if __name__ == '__main__': @@ -926,8 +929,8 @@ def test_ExportDevice_unsupported(): test_Synapses() test_ExportDevice_options() test_ExportDevice_basic() - test_ExportDevice_unsupported() # TODO: not checking anything + test_ExportDevice_unsupported() test_synapse_init() test_synapse_connect_cond() test_synapse_connect_generator() - test_synapse_connect_ij() + test_synapse_connect_ij() \ No newline at end of file diff --git a/brian2tools/tests/test_plotting.py b/brian2tools/tests/test_plotting.py index 1b6fd085..e1ec6a29 100644 --- a/brian2tools/tests/test_plotting.py +++ b/brian2tools/tests/test_plotting.py @@ -122,6 +122,20 @@ def test_plot_morphology(): ax = plot_dendrogram(morpho) assert isinstance(ax, matplotlib.axes.Axes) plt.close() + # Test that styling kwargs are accepted and forwarded without error + ax = plot_dendrogram(morpho, color='red') + assert isinstance(ax, matplotlib.axes.Axes) + plt.close() + ax = plot_dendrogram(morpho, color='blue', alpha=0.5) + assert isinstance(ax, matplotlib.axes.Axes) + plt.close() + ax = plot_dendrogram(morpho, color='green', linewidth=3) + assert isinstance(ax, matplotlib.axes.Axes) + plt.close() + # brian_plot routes Morphology to plot_dendrogram, so kwargs must work there too + ax = brian_plot(morpho, color='purple') + assert isinstance(ax, matplotlib.axes.Axes) + plt.close() ax = plot_morphology(morpho) assert isinstance(ax, matplotlib.axes.Axes) plt.close() diff --git a/docs_sphinx/user/plotting.rst b/docs_sphinx/user/plotting.rst index 0b8420f4..2e87c2b2 100644 --- a/docs_sphinx/user/plotting.rst +++ b/docs_sphinx/user/plotting.rst @@ -229,8 +229,18 @@ dendogram:: .. image:: ../images/plot_dendrogram.svg The `~brian2tools.plotting.morphology.plot_dendrogram` function does the same thing, but in contrast to the other -plot functions it does not allow any customization at the moment, so there is no benefit over using -`~brian2tools.plotting.base.brian_plot`. +plot functions it does not allow any customization that is not also available via +`~brian2tools.plotting.base.brian_plot`. Both functions accept additional keyword arguments (e.g. ``color``, +``alpha``, ``linewidth``) that are forwarded to the underlying `~matplotlib.axes.Axes.plot`, +`~matplotlib.axes.Axes.vlines`, and `~matplotlib.axes.Axes.hlines` calls:: + + plot_dendrogram(morpho, color='red', alpha=0.7) + +.. image:: ../images/plot_dendrogram_custom.svg + +The same customization is also possible via `~brian2tools.plotting.base.brian_plot`:: + + brian_plot(morpho, color='red', alpha=0.7) .. _plotting_morphologies: