def _do_plot(self, val_min, val_max, sections, variable, cmap=cm.cool, **kwargs): """ Plots a 3D shapeplot Args: sections = list of h.Section() objects to be plotted **kwargs passes on to matplotlib (e.g. linewidth=2 for thick lines) Returns: lines = list of line objects making up shapeplot """ # Adapted from # https://github.com/ahwillia/PyNeuron-Toolbox/blob/master/PyNeuronToolbox/morphology.py # Accessed 2019-04-11, which had an MIT license # Default is to plot all sections. if sections is None: sections = list(h.allsec()) h.define_shape() # default color is black kwargs.setdefault('color', 'black') # Plot each segement as a line lines = {} lines_list = [] vals = [] for sec in sections: all_seg_pts = _segment_3d_pts(sec) for seg, (xs, ys, zs, _, _) in zip(sec, all_seg_pts): line, = self.plot(xs, ys, zs, '-', **kwargs) if variable is not None: try: if '.' in variable: mech, var = variable.split('.') val = getattr(getattr(seg, mech), var) else: val = getattr(seg, variable) except AttributeError: # leave default color if no variable found val = None vals.append(val) lines[line] = '%s at %s' % (val, seg) lines_list.append(line) if variable is not None: val_range = val_max - val_min if val_range: for sec in sections: for line, val in zip(lines_list, vals): if val is not None: col = cmap( int(255 * (val - val_min) / (val_range))) line.set_color(col) return lines
def _do_plot_on_plotly(): """requires matplotlib for colormaps if not specified explicitly""" import ctypes import plotly.graph_objects as go class FigureWidgetWithNEURON(go.FigureWidget): def mark(self, segment, marker='or', **kwargs): """plot a marker on a segment Args: segment = the segment to mark **kwargs = passed to go.Scatter3D plot """ x, y, z = _get_3d_pt(segment) # approximately match the appearance of the matplotlib defaults kwargs.setdefault('marker_size', 5) kwargs.setdefault('marker_color', 'red') kwargs.setdefault('marker_opacity', 1) self.add_trace( go.Scatter3d( x=[x], y=[y], z=[z], name='', hovertemplate=str(segment), **kwargs ) ) return self get_plotshape_data = nrn_dll_sym('get_plotshape_data') get_plotshape_data.restype = ctypes.py_object variable, varobj, lo, hi, secs = get_plotshape_data(ctypes.py_object(self._data)) if varobj is not None: variable = varobj if secs is None: secs = list(h.allsec()) if variable is None: kwargs.setdefault('color', 'black') data = [] for sec in secs: xs = [sec.x3d(i) for i in range(sec.n3d())] ys = [sec.y3d(i) for i in range(sec.n3d())] zs = [sec.z3d(i) for i in range(sec.n3d())] data.append( go.Scatter3d( x=xs, y=ys, z=zs, name='', hovertemplate=str(sec), mode="lines", line=go.scatter3d.Line( color=kwargs['color'], width=2 )) ) return FigureWidgetWithNEURON(data=data, layout={'showlegend': False}) else: if 'cmap' not in kwargs: # use same default colormap as the matplotlib version from matplotlib.pyplot import cm kwargs['cmap'] = cm.cool cmap = kwargs['cmap'] show_diam = False # calculate bounds val_range = hi - lo data = [] for sec in secs: all_seg_pts = _segment_3d_pts(sec) for seg, (xs, ys, zs, _, _) in zip(sec, all_seg_pts): val = _get_variable_seg(seg, variable) hover_template = str(seg) if val is not None: hover_template += '<br>' + ('%.3f' % val) col = _get_color(variable, val, cmap, lo, hi, val_range) if show_diam: diam = seg.diam else: diam = 2 data.append( go.Scatter3d( x=xs, y=ys, z=zs, name='', hovertemplate=hover_template, mode="lines", line=go.scatter3d.Line( color=col, width=diam )) ) return FigureWidgetWithNEURON(data=data, layout={'showlegend': False})
def _do_plot(self, val_min, val_max, sections, variable, cmap=cm.cool, **kwargs): """ Plots a 3D shapeplot Args: sections = list of h.Section() objects to be plotted **kwargs passes on to matplotlib (e.g. linewidth=2 for thick lines) Returns: lines = list of line objects making up shapeplot """ # Adapted from # https://github.com/ahwillia/PyNeuron-Toolbox/blob/master/PyNeuronToolbox/morphology.py # Accessed 2019-04-11, which had an MIT license # Default is to plot all sections. if sections is None: sections = list(h.allsec()) h.define_shape() # default color is black kwargs.setdefault("color", "black") # Plot each segement as a line lines = {} lines_list = [] vals = [] for sec in sections: all_seg_pts = _segment_3d_pts(sec) for seg, (xs, ys, zs, _, _) in zip(sec, all_seg_pts): (line, ) = self.plot(xs, ys, zs, "-", **kwargs) if variable is not None: val = _get_variable_seg(seg, variable) vals.append(val) if val is not None: lines[line] = "%s at %s" % (val, seg) else: lines[line] = str(seg) else: lines[line] = str(seg) lines_list.append(line) if variable is not None: val_range = val_max - val_min if val_range: for sec in sections: for line, val in zip(lines_list, vals): if val is not None: col = _get_color( variable, val, cmap, val_min, val_max, val_range, ) line.set_color(col) return lines