def test_bokeh(): from bokeh.io import output_notebook, show from bokeh.plotting import figure import ipyvolume.bokeh x, y, z = np.random.random((3, 100)) p3.figure() scatter = p3.scatter(x, y, z) tools = "wheel_zoom,box_zoom,box_select,lasso_select,help,reset," p = figure(title="E Lz space", tools=tools, webgl=True, width=500, height=500) r = p.circle(x, y, color="navy", alpha=0.2) ipyvolume.bokeh.link_data_source_selection_to_widget( r.data_source, scatter, 'selected') from bokeh.resources import CDN from bokeh.embed import components script, div = components(p) ipyvolume.embed.embed_html( "tmp/bokeh.html", [p3.gcc(), ipyvolume.bokeh.wmh], all=True, extra_script_head=script + CDN.render_js() + CDN.render_css(), body_pre="<h2>Do selections in 2d (bokeh)<h2>" + div + "<h2>And see the selection in ipyvolume<h2>")
def show_image(index=0): p3.figure() p3.volshow(indexed_timeseries.data[index], tf=linear_transfer_function([0, 0, 0], max_opacity=.3)) output.clear_output(wait=True) with output: p3.show()
def plot_soma_3d(neurons_df, color_by='cellBodyFiber', point_size=1.0): """ Plot the soma locations in 3D, colored randomly according to the column given in ``color_by``. Requires ``ipyvolume``. If using Jupyterlab, install it like this: .. code-block: bash conda install -c conda-forge ipyvolume jupyter labextension install ipyvolume Example: .. code-block: python from neuprint import fetch_neurons, NeuronCriteria as NC criteria = NC(status='Traced', cropped=False) neurons_df, _roi_counts_df = fetch_neurons(criteria) plot_soma_3d(neurons_df, 'cellBodyFiber') """ import ipyvolume.pylab as ipv neurons_df = neurons_df[['somaLocation', color_by]].copy() extract_soma_coords(neurons_df) assign_colors(neurons_df, color_by) neurons_with_soma_df = neurons_df.query('not somaLocation.isnull()') assert neurons_with_soma_df.eval('color.isnull()').sum() == 0 soma_x = neurons_with_soma_df['soma_x'].values soma_y = neurons_with_soma_df['soma_y'].values soma_z = neurons_with_soma_df['soma_z'].values def color_to_vals(color_string): # Convert bokeh color string into float tuples, # e.g. '#00ff00' -> (0.0, 1.0, 0.0) s = color_string return (int(s[1:3], 16) / 255, int(s[3:5], 16) / 255, int(s[5:7], 16) / 255) color_vals = neurons_with_soma_df['color'].apply(color_to_vals).tolist() # DVID coordinate system assumes (0,0,0) is in the upper-left. # For consistency with DVID and neuroglancer conventions, # we invert the Y and X coordinates. ipv.figure() ipv.scatter(soma_x, -soma_y, -soma_z, color=color_vals, marker="circle_2d", size=point_size) ipv.show()
def plot(self, plot_mesh=True, plot_voxels=True, width=800, height=600, voxel_count_offset=0, voxel_limit=None, use_centroids_instead=False, scaling=1, mesh_color='red', **kwargs): """ This method needs better documentation. :param **kwargs: Is used in ipyvolume.pylab.scatter() or ipyvolume.pylab.plot() depending on whether use_centroids_instead is set to true or not. """ if plot_mesh: if self.triangles is None: raise ValueError( "There is no triangle data stored for this mesh!") else: fig = p3.figure(width=width, height=height) p3.plot_trisurf(*self.vertices.T * scaling, self.triangles, color=mesh_color) if plot_voxels: self.voxels.plot( width=width, height=height, voxel_count_offset=voxel_count_offset, voxel_limit=voxel_limit, use_centroids_instead=use_centroids_instead, ipyvol_fig=fig, scaling=scaling, **kwargs) else: p3.squarelim() p3.show() elif plot_voxels: try: fig = p3.figure(width=width, height=height) self.voxels.plot(width=width, height=height, voxel_count_offset=voxel_count_offset, voxel_limit=voxel_limit, use_centroids_instead=use_centroids_instead, ipyvol_fig=fig, scaling=scaling, **kwargs) except AttributeError: raise AttributeError( "This object does not have a Voxels object, you must initialize the voxel mesh with a Voxels object or run voxelize() to generate new voxels." )
def update_figure(index=0): p3.figure() p3.volshow( indexed_timeseries.data[index].transpose([1, 0, 2]), tf=linear_transfer_function([0, 0, 0], max_opacity=0.3), ) output.clear_output(wait=True) self.figure = output with output: p3.show()
def plot(self, width=800, height=600, voxel_count_offset=0, voxel_limit=None, use_centroids_instead=False, ipyvol_fig=None, scaling=1, **kwargs): """ This method needs better documentation. :param **kwargs: Is used in ipyvolume.pylab.scatter() or ipyvolume.pylab.plot() depending on whether use_centroids_instead is set to true or not. """ if ipyvol_fig is None: p3.figure(width=width, height=height) else: p3.figure(ipyvol_fig) voxels_length = len(self) if voxel_count_offset >= voxels_length: raise ValueError( "voxel_count_offset is greater than the number of voxels!") else: if voxel_limit is None: n_voxels_to_plot = len(self) else: n_voxels_to_plot = voxel_count_offset + voxel_limit if n_voxels_to_plot > voxels_length: n_voxels_to_plot = len(self) if use_centroids_instead: if 'marker' not in kwargs: kwargs['marker'] = 'sphere' if 'color' not in kwargs: kwargs['color'] = 'blue' if 'size' not in kwargs: kwargs['size'] = 0.5 p3.scatter( *self.centroids[voxel_count_offset:n_voxels_to_plot].T * scaling, **kwargs) else: voxel_count_offset *= 18 n_voxels_to_plot *= 18 drawable_bboxes = self.drawable_bboxes[ voxel_count_offset:n_voxels_to_plot] p3.plot(*drawable_bboxes.T * scaling, **kwargs) p3.squarelim() p3.show()
def _init_figure(self, x, y, z, triangles, figsize, figlims): """ Initialize the figure by plotting the surface without any overlay. x: x coordinates of vertices (V x 1 numpy array) y: y coordinates of vertices (V x 1 numpy array) z: z coordinates of vertices (V x 1 numpy array) triangles: triangle specifications (T x 3 numpy array, where T=#triangles) figsize: 2x1 list of integers figlims: 3x2 list of integers """ self.fig = p3.figure(width=figsize[0], height=figsize[1]) self.fig.camera_fov = 1 self.fig.style = { "axes": { "color": "black", "label": {"color": "black"}, "ticklabel": {"color": "black"}, "visible": False, }, "background-color": "white", "box": {"visible": False}, } self.fig.xlim = (figlims[0][0], figlims[0][1]) self.fig.ylim = (figlims[1][0], figlims[1][1]) self.fig.zlim = (figlims[2][0], figlims[2][1]) # draw the tetrahedron p3.plot_trisurf( x, y, z, triangles=triangles, color=np.ones((len(x), 3)) )
def show_grayscale_volume(vol: GrayscaleVolume, neurodata_vis_spec: dict): import ipyvolume.pylab as p3 fig = p3.figure() p3.volshow(vol.data, tf=linear_transfer_function([0, 0, 0], max_opacity=0.1)) return fig
def plot3d(self, threshold=0.5): """Display the reconstructed intensities as an Jupyter widget using ipyvolume. """ if isinstance(self.I, da.core.Array): raise ValueError("Cannot display dask arrays.") sel = self.I > threshold print(f"Displaying {np.where(sel)[0].size} points...") fig = p3.figure() cmap = plt.cm.gray color = cmap(self.I[sel] / self.I.max()) try: s = p3.scatter( self.X[sel], self.Y[sel], self.Z[sel], color=color, marker="sphere", ) except AttributeError: grid_sel = self.grid[sel] s = p3.scatter( grid_sel[:, 0], grid_sel[:, 1], grid_sel[:, 2], color=color, marker="sphere", ) s.size = self.I[sel] / self.I.max() * 5 p3.view(90, 0) return fig, s
def test_widgets_state(performance): try: _remove_buffers = None try: from ipywidgets.widgets.widget import _remove_buffers except: pass ipyvolume.serialize.performance = performance x, y, z = np.random.random((3, 100)) p3.figure() scatter = p3.scatter(x, y, z) state = scatter.get_state() if _remove_buffers: _remove_buffers(state) else: scatter._split_state_buffers(state) finally: ipyvolume.serialize.performance = 0
def create_widget(self, output, plot, dataset, limits): self.output = output self.plot = plot self.dataset = dataset self.limits = np.array(limits).tolist() self._first_time = True self._first_time_vector = True self.figure = p3.figure() self.widget = p3.gcc()
def plot_group_brain_activation(self, radius=12.5, freq_range=(40, 200), clim=None, cmap='RdBu_r'): """ Plots brain surface based on the mean activity across the group. Uses ipyvolume to plot Parameters ---------- radius: float Maximum distance between an electrode and a vertex to be counted as data for that vertex freq_range: list 2 element list defining minimum and maximum frequncies to average. clim: float Maximum/minumum value of the colormap. Will be centered at zero. If not given, will use the maximum absolute value of the data. cmap: str matplotlib colormap to use Returns ------- left hemisphere and right hemisphere activation maps """ # load brain mesh l_coords, l_faces, r_coords, r_faces = self.load_brain_mesh() # compute mean activation l_vert_mean, r_vert_mean = self.compute_surface_map(radius, freq_range) # define colormap range if clim is None: clim = np.max([np.nanmax(np.abs(l_vert_mean)), np.nanmax(np.abs(r_vert_mean))]) c_norm = plt.Normalize(vmin=-clim, vmax=clim) c_mappable = cmx.ScalarMappable(norm=c_norm, cmap=plt.get_cmap(cmap)) # compute surface colors for left valid_l_inds = ~np.isnan(l_vert_mean) l_colors = np.full((l_vert_mean.shape[0], 4), 0.) l_colors[valid_l_inds] = c_mappable.to_rgba(l_vert_mean[valid_l_inds]) # and right valid_r_inds = ~np.isnan(r_vert_mean) r_colors = np.full((r_vert_mean.shape[0], 4), 0.) r_colors[valid_r_inds] = c_mappable.to_rgba(r_vert_mean[valid_r_inds]) # plot it! fig = p3.figure(width=800, height=800, lighting=True) brain_l = p3.plot_trisurf(l_coords[:, 0], l_coords[:, 1], l_coords[:, 2], triangles=l_faces, color=l_colors) brain_r = p3.plot_trisurf(r_coords[:, 0], r_coords[:, 1], r_coords[:, 2], triangles=r_faces, color=r_colors) # turn off axis and make square ipv.squarelim() ipv.style.box_off() ipv.style.axes_off() p3.show() return fig
def create_widget(self, output, plot, dataset, limits): self.output = output self.plot = plot self.dataset = dataset self.limits = np.array(limits).tolist() self._first_time = True self._first_time_vector = True self.figure = p3.figure() self.widget = p3.gcc() self.figure.observe(self._update_limits, 'xlim ylim zlim'.split())
def test_labels(): f = p3.figure() p3.xlabel("x1") p3.ylabel("y1") p3.zlabel("z1") assert f.xlabel == "x1" assert f.ylabel == "y1" assert f.zlabel == "z1" p3.xyzlabel("x2", "y2", "z2") assert f.xlabel == "x2" assert f.ylabel == "y2" assert f.zlabel == "z2"
def show_plane_segmentation_3d_mask(plane_seg: PlaneSegmentation): import ipyvolume.pylab as p3 nrois = len(plane_seg) image_masks = plane_seg["image_mask"] fig = p3.figure() for icolor, color in enumerate(color_wheel): vol = np.zeros(image_masks.shape[1:]) sel = np.arange(icolor, nrois, len(color_wheel)) for isel in sel: vol += plane_seg["image_mask"][isel] p3.volshow(vol, tf=linear_transfer_function(color, max_opacity=0.3)) return fig
def show_plane_segmentation_3d(plane_seg: PlaneSegmentation): import ipyvolume.pylab as p3 nrois = len(plane_seg) dims = np.array([max(max(plane_seg['voxel_mask'][i][dim]) for i in range(nrois)) for dim in ['x', 'y', 'z']]).astype('int') + 1 fig = p3.figure() for icolor, color in enumerate(color_wheel): vol = np.zeros(dims) sel = np.arange(icolor, nrois, len(color_wheel)) for isel in sel: dat = plane_seg['voxel_mask'][isel] vol[tuple(dat['x'].astype('int')), tuple(dat['y'].astype('int')), tuple(dat['z'].astype('int'))] = 1 p3.volshow(vol, tf=linear_transfer_function(color, max_opacity=.3)) return fig
def test_limits(): f = p3.figure() p3.xlim(-10, 11) assert f.xlim[0] == -10 assert f.xlim[1] == 11 p3.ylim(-12, 13) assert f.ylim[0] == -12 assert f.ylim[1] == 13 p3.zlim(-14, 15) assert f.zlim[0] == -14 assert f.zlim[1] == 15 p3.xyzlim(-17, 17) assert f.xlim[0] == -17 assert f.xlim[1] == 17 assert f.ylim[0] == -17 assert f.ylim[1] == 17 assert f.zlim[0] == -17 assert f.zlim[1] == 17
def show_spatial_series(node: SpatialSeries, **kwargs): data, unit = get_timeseries_in_units(node) tt = get_timeseries_tt(node) if len(data.shape) == 1: fig, ax = plt.subplots() ax.plot(tt, data, **kwargs) ax.set_xlabel('t (sec)') if unit: ax.set_xlabel('x ({})'.format(unit)) else: ax.set_xlabel('x') ax.set_ylabel('x') elif data.shape[1] == 2: fig, ax = plt.subplots() ax.plot(data[:, 0], data[:, 1], **kwargs) if unit: ax.set_xlabel('x ({})'.format(unit)) ax.set_ylabel('y ({})'.format(unit)) else: ax.set_xlabel('x') ax.set_ylabel('y') ax.axis('equal') elif data.shape[1] == 3: import ipyvolume.pylab as p3 fig = p3.figure() p3.scatter(data[:, 0], data[:, 1], data[:, 2], **kwargs) p3.xlim(np.min(data[:, 0]), np.max(data[:, 0])) p3.ylim(np.min(data[:, 1]), np.max(data[:, 1])) p3.zlim(np.min(data[:, 2]), np.max(data[:, 2])) else: raise NotImplementedError return fig
def test_limits(): f = p3.figure() p3.xlim(-10, 11) assert f.xlim[0] == -10 assert f.xlim[1] == 11 p3.ylim(-12, 13) assert f.ylim[0] == -12 assert f.ylim[1] == 13 p3.zlim(-14, 15) assert f.zlim[0] == -14 assert f.zlim[1] == 15 p3.xyzlim(-17, 17) assert f.xlim[0] == -17 assert f.xlim[1] == 17 assert f.ylim[0] == -17 assert f.ylim[1] == 17 assert f.zlim[0] == -17 assert f.zlim[1] == 17 # TODO: actually, default xlim should be None, and the limits should # then now grow, but 'move' around the new point f = ipv.figure() assert f.xlim == [0, 1] ipv.ylim(0, 10) ipv.zlim(-10, 0) ipv.scatter(3, 4, 5) assert f.xlim == [0, 3] assert f.ylim == [0, 10] assert f.zlim == [-10, 5] f = ipv.figure() ipv.volshow(np.random.rand(5, 5, 5), extent=[[0.1, 0.9], [0.5, 2], [-2, 5]]) assert f.xlim == [0, 1] assert f.ylim == [0, 2] assert f.zlim == [-2, 5]
def show_plane_segmentation_3d_voxel(plane_seg: PlaneSegmentation): import ipyvolume.pylab as p3 nrois = len(plane_seg) voxel_mask = plane_seg["voxel_mask"] mx, my, mz = 0, 0, 0 for voxel in voxel_mask: for x, y, z, _ in voxel: mx = max(mx, x) my = max(my, y) mz = max(mz, z) fig = p3.figure() for icolor, color in enumerate(color_wheel): vol = np.zeros((mx + 1, my + 1, mz + 1)) sel = np.arange(icolor, nrois, len(color_wheel)) for isel in sel: dat = voxel_mask[isel] for x, y, z, value in dat: vol[x, y, z] = value p3.volshow(vol, tf=linear_transfer_function(color, max_opacity=0.3)) return fig
def test_figure(): f1 = p3.figure() f2 = p3.figure(2) f3 = p3.figure() f4 = p3.figure(2) f5 = p3.gcf() p3.clear() f6 = p3.gcf() assert f1 != f2 assert f2 != f3 assert f3 != f4 assert f2 == f2 assert f4 == f5 assert f5 != f6 for controls in [True, False]: for debug in [True, False]: p3.figure(debug=debug, controls=controls)
def quickscatter(x, y, z, **kwargs): import ipyvolume.pylab as p3 p3.figure() p3.scatter(x, y, z, **kwargs) return p3.current.container
def quickquiver(x, y, z, u, v, w, **kwargs): import ipyvolume.pylab as p3 p3.figure() p3.quiver(x, y, z, u, v, w, **kwargs) return p3.current.container
import ipyvolume.pylab as p3 import numpy as np fig = p3.figure() q = p3.quiver(*stream.data[:,0:50,:200], color="red", size=7) p3.style.use("dark") # looks better p3.animation_control(q, interval=200) p3.show()
def plot_group_brain_activation(self, radius=12.5, freq_range=(40, 200), clim=None, cmap='RdBu_r', n_perms=100, min_n=5): """ Plots brain surface based on the mean activity across the group. Uses ipyvolume to plot Parameters ---------- radius: float Maximum distance between an electrode and a vertex to be counted as data for that vertex freq_range: list 2 element list defining minimum and maximum frequncies to average. clim: float Maximum/minumum value of the colormap. Will be centered at zero. If not given, will use the maximum absolute value of the data. cmap: str matplotlib colormap to use n_perms: int Number of permutations to do when computing our t-statistic significance thresholds min_n: int Vertices with less than this number of subjects will be plotted in gray, regardless of the significance val Returns ------- left hemisphere and right hemisphere activation maps """ # load brain mesh l_coords, l_faces, r_coords, r_faces = self.load_brain_mesh() # compute mean activation. First get vertex x subject arrays l_vert_vals, r_vert_vals = self.compute_surface_map(radius, freq_range) # we will actually be plotting t-statistics, so compute those l_ts, l_ps = ttest_1samp(l_vert_vals, 0, axis=1, nan_policy='omit') r_ts, r_ps = ttest_1samp(r_vert_vals, 0, axis=1, nan_policy='omit') # not let's compute our significance thresholds via non-parametric permutation procedure sig_thresh = self.compute_permute_dist_par(l_vert_vals, r_vert_vals, n_perms=n_perms) # define colormap range if clim is None: clim = np.max([np.nanmax(np.abs(l_ts)), np.nanmax(np.abs(r_ts))]) c_norm = plt.Normalize(vmin=-clim, vmax=clim) c_mappable = cmx.ScalarMappable(norm=c_norm, cmap=plt.get_cmap(cmap)) # compute surface colors for left valid_l_inds = ~np.isnan(l_ts) & (np.sum(np.isnan(l_vert_vals), axis=1) >= min_n) l_colors = np.full((l_ts.shape[0], 4), 0.) l_colors[valid_l_inds] = c_mappable.to_rgba(l_ts[valid_l_inds]) # and right valid_r_inds = ~np.isnan(r_ts) & (np.sum(np.isnan(r_vert_vals), axis=1) >= min_n) r_colors = np.full((r_ts.shape[0], 4), 0.) r_colors[valid_r_inds] = c_mappable.to_rgba(r_ts[valid_r_inds]) # lastly, mask out vertices that do not meet our significance thresh sig_l = (l_ts < sig_thresh[0]) | (l_ts > sig_thresh[1]) sig_r = (r_ts < sig_thresh[0]) | (r_ts > sig_thresh[1]) l_colors[~sig_l] = [.7, .7, .7, 0.] r_colors[~sig_r] = [.7, .7, .7, 0.] # plot it! fig = p3.figure(width=800, height=800, lighting=True) brain_l = p3.plot_trisurf(l_coords[:, 0], l_coords[:, 1], l_coords[:, 2], triangles=l_faces, color=l_colors) brain_r = p3.plot_trisurf(r_coords[:, 0], r_coords[:, 1], r_coords[:, 2], triangles=r_faces, color=r_colors) # turn off axis and make square ipv.squarelim() ipv.style.box_off() ipv.style.axes_off() p3.show() return fig
def plot_skeleton_3d(skeleton, color='blue', *, client=None): """ Plot the given skeleton in 3D. Args: skeleton: Either a bodyId or a pre-fetched pandas DataFrame color: See ``ipyvolume`` docs. Examples: ``'blue'``, ``'#0000ff'`` If the skeleton is fragmented, you can give a list of colors and each fragment will be shown in a different color. Requires ``ipyvolume``. If using Jupyterlab, install it like this: .. code-block: bash conda install -c conda-forge ipyvolume jupyter labextension install ipyvolume """ import ipyvolume.pylab as ipv if np.issubdtype(type(skeleton), np.integer): skeleton = client.fetch_skeleton(skeleton, format='pandas') assert isinstance(skeleton, pd.DataFrame) g = skeleton_df_to_nx(skeleton) def skel_path(root): """ We want to plot each skeleton fragment as a single continuous line, but that means we have to backtrack: parent -> leaf -> parent to avoid jumping from one branch to another. This means that the line will be drawn on top of itself, and we'll have 2x as many line segments in the plot, but that's not a big deal. """ def accumulate_points(n): p = (g.nodes[n]['x'], g.nodes[n]['y'], g.nodes[n]['z']) points.append(p) children = [*g.successors(n)] if not children: return for c in children: accumulate_points(c) points.append(p) points = [] accumulate_points(root) return np.asarray(points) # Skeleton may contain multiple fragments, # so compute the path for each one. def skel_paths(df): paths = [] for root in df.query('link == -1')['rowId']: paths.append(skel_path(root)) return paths paths = skel_paths(skeleton) if isinstance(color, str): colors = len(paths) * [color] else: colors = (1 + len(paths) // len(color)) * color ipv.figure() for points, color in zip(paths, colors): ipv.plot(*points.transpose(), color) ipv.show()
def create_plot(self): self._first_time = True self.figure = p3.figure()
# apply transform to the parametric shape coordinates Xc = np.ndarray((k, Xco.shape[0], Xco.shape[1])) Yc = np.ndarray((k, Yco.shape[0], Yco.shape[1])) Zc = np.ndarray((k, Zco.shape[0], Zco.shape[1])) Xf = np.ndarray((k, Xfo.shape[0], Xfo.shape[1])) Yf = np.ndarray((k, Yfo.shape[0], Yfo.shape[1])) Zf = np.ndarray((k, Zfo.shape[0], Zfo.shape[1])) for i in range(0, k): (Xc[i, :, :], Yc[i, :, :], Zc[i, :, :]) = shape_xform(Xco, Yco, Zco, Tr[i]) (Xf[i, :, :], Yf[i, :, :], Zf[i, :, :]) = shape_xform(Xfo, Yfo, Zfo, Tr[i]) # In[ ]: # create ipyvolume figure to display cylinder and coordinate frame transform animation fig = p3.figure(width=480, height=480) # set ipyvolume style properties p3.style.background_color('black') p3.style.box_off() p3.style.use("dark") p3.style.use({'xaxis.color': "red"}) # <-+ p3.style.use({'yaxis.color': "green"}) # <-+- do not appear to be working p3.style.use({'zaxis.color': "blue"}) # <-+ # set figure view and axes p3.view(0.0, -120.0) p3.xyzlim(-2.0, 2.0) p3.xyzlabel('X', 'Y', 'Z') # coordinate frame axes line segments
def showSurface(surface,overlay=None,frame=0,newfigure=True,colormap='summer',figsize=np.array([300,400]), figlims=np.array([[-75,75],[-75,75],[-75,75]])): ''' Displays a surface mesh in gifti or FreeSurfer (FS) surface format with/without an overlay inside Jupyter notebook for interactive visualization. Parameters ---------- surface: str, gifti opject Path to surface file in gifti or FS surface format or an already loaded gifti object of surface overlay: str, gifti opject Path to overlay file in gifti or FS annot or anaotimcal (.curv,.sulc,.thickness) format or an already loaded gifti object of overlay, default None frame: int indice of the frame (timepoint or functional data frame) to show newfigure: bool Create a new figure else prints into the last figure (in order to visualize both hemispheres in one plot), default True colormap: string A matplotlib colormap, default summer figsize: ndarray Size of the figure to display, default [600,600] figLims: ndarray x,y and z limits of the axes, default [[-100,100],[-100,100],[-100,100]]) ''' if isinstance(surface,str): if not os.path.exists(surface): error('File does not exist, please provide a valid file path to a gifti or FreeSurfer file.') filename, file_extension = os.path.splitext(surface) if file_extension is '.gii': surface = nb.load(surface) else: fsgeometry = nb.freesurfer.read_geometry(surface) x,y,z = fsgeometry[0].T vertex_edges=fsgeometry[1] if isinstance(surface,nb.gifti.gifti.GiftiImage): try: vertex_spatial=surface.darrays[0] vertex_edges=surface.darrays[1] x, y, z = vertex_spatial.data.T except: raise ValueError('Please provide a valid gifti file.') if not isinstance(frame,int): ValueError('Please provide a valid integer frame index.') if isinstance(overlay,list): if frame>len(overlay) or frame < 0: error('Frame index out of bounds, please provide a valid frame index.') overlay = overlay[frame] if isinstance(overlay,str): if not os.path.exists(overlay): error('File does not exist, please provide a valid file path to a gifti or FreeSurfer file.') filename, file_extension = os.path.splitext(overlay) if file_extension is '.gii': overlay = nb.load(overlay) elif (file_extension in ('.annot','')): annot = nb.freesurfer.read_annot(overlay) activation = annot[0] elif (file_extension in ('.curv','.thickness','.sulc')): activation = nb.freesurfer.read_morph_data(overlay) if isinstance(overlay,nb.gifti.gifti.GiftiImage): try: activation=overlay.darrays[0].data except: raise ValueError('Please provide a valid gifti file') if newfigure: fig = p3.figure(width=figsize[0], height=figsize[1]) fig.camera_fov = 1 fig.style = {'axes': {'color': 'black', 'label': {'color': 'black'}, 'ticklabel': {'color': 'black'}, 'visible': False}, 'background-color': 'white', 'box': {'visible': False}} fig.xlim = (figlims[0][0], figlims[0][1]) fig.ylim = (figlims[1][0], figlims[1][1]) fig.zlim = (figlims[2][0], figlims[2][1]) # plot surface if overlay is None: p3.plot_trisurf(x, y, z, triangles=vertex_edges.data) else: my_color = plt.cm.get_cmap(colormap) colors=my_color((activation-min(activation))/(max(activation)-min(activation))) p3.plot_trisurf(x, y, z, triangles=vertex_edges.data, color=colors[:,:3]) if newfigure: p3.show()
def plot_group_brain_activation(self, radius=12.5, freq_range=(40, 200), clim=None, cmap='RdBu_r', n_perms=100, min_n=5, res_key='t-stat'): """ Plots brain surface based on the mean activity across the group. Uses ipyvolume to plot Parameters ---------- radius: float Maximum distance between an electrode and a vertex to be counted as data for that vertex freq_range: list 2 element list defining minimum and maximum frequncies to average. clim: float Maximum/minumum value of the colormap. Will be centered at zero. If not given, will use the maximum absolute value of the data. cmap: str matplotlib colormap to use n_perms: int Number of permutations to do when computing our t-statistic significance thresholds min_n: int Vertices with less than this number of subjects will be plotted in gray, regardless of the significance val res_key: str Column name of dataframe to use as the metric Returns ------- left hemisphere and right hemisphere activation maps """ # load brain mesh l_coords, l_faces, r_coords, r_faces = self.load_brain_mesh() # compute mean activation. First get vertex x subject arrays l_vert_vals, r_vert_vals = self.compute_surface_map(radius, freq_range, res_key) # we will actually be plotting t-statistics, so compute those l_ts, l_ps = ttest_1samp(l_vert_vals, 0, axis=1, nan_policy='omit') r_ts, r_ps = ttest_1samp(r_vert_vals, 0, axis=1, nan_policy='omit') # not let's compute our significance thresholds via non-parametric permutation procedure sig_thresh = self.compute_permute_dist_par(l_vert_vals, r_vert_vals, n_perms=n_perms) # define colormap range if clim is None: clim = np.max([np.nanmax(np.abs(l_ts)), np.nanmax(np.abs(r_ts))]) c_norm = plt.Normalize(vmin=-clim, vmax=clim) c_mappable = cmx.ScalarMappable(norm=c_norm, cmap=plt.get_cmap(cmap)) # compute surface colors for left valid_l_inds = ~np.isnan(l_ts) & (np.sum(np.isnan(l_vert_vals), axis=1) >= min_n) l_colors = np.full((l_ts.shape[0], 4), 0.) l_colors[valid_l_inds] = c_mappable.to_rgba(l_ts[valid_l_inds]) # and right valid_r_inds = ~np.isnan(r_ts) & (np.sum(np.isnan(r_vert_vals), axis=1) >= min_n) r_colors = np.full((r_ts.shape[0], 4), 0.) r_colors[valid_r_inds] = c_mappable.to_rgba(r_ts[valid_r_inds]) # lastly, mask out vertices that do not meet our significance thresh sig_l = (l_ts < sig_thresh[0]) | (l_ts > sig_thresh[1]) sig_r = (r_ts < sig_thresh[0]) | (r_ts > sig_thresh[1]) l_colors[~sig_l] = [.7, .7, .7, 0.] r_colors[~sig_r] = [.7, .7, .7, 0.] # plot it! fig = p3.figure(width=800, height=800, lighting=True) brain_l = p3.plot_trisurf(l_coords[:, 0], l_coords[:, 1], l_coords[:, 2], triangles=l_faces, color=l_colors) brain_r = p3.plot_trisurf(r_coords[:, 0], r_coords[:, 1], r_coords[:, 2], triangles=r_faces, color=r_colors) # turn off axis and make square ipv.squarelim() ipv.style.box_off() ipv.style.axes_off() p3.show() return fig
def test_figure(): f1 = p3.figure() f2 = p3.figure(2) f3 = p3.figure() f4 = p3.figure(2) f5 = p3.gcf() p3.clear() f6 = p3.gcf() assert f1 != f2 assert f2 != f3 assert f3 != f4 assert f2 == f2 assert f4 == f5 assert f5 != f6 f7 = p3.figure('f7') f8 = p3.figure() f9 = p3.figure('f7') f10 = p3.figure(f8) f11 = p3.gcf() f12 = p3.current.figure f13 = p3.figure('f7') f14 = p3.current.figures['f7'] assert f7 == f9 assert f8 == f10 assert f10 == f11 assert f11 == f12 assert f13 == f14 for controls in [True, False]: for debug in [True, False]: p3.figure(debug=debug, controls=controls)
# ax = fig.add_subplot(111, projection='3d') # ax.scatter(xs, ys, zs, marker='o', alpha=0.1, s=1) # plt.show() # # fig = plt.figure(figsize=(6,6)) # # ax = fig.add_subplot(111, projection='3d') # xs,ys,zs = np.where(label_data == 1) # ax.scatter(xs, ys, zs, marker='o',color='g', alpha=0.1, s=5) # plt.show() # In[48]: import ipyvolume.pylab as p3 p3.figure(figsize=(15,15)) ipyvolume.quickvolshow(islands, opacity=1) ipyvolume.quickvolshow(label_data, opacity=1) # In[35]: x,y,z = np.where(label_data == 1) ipyvolume.quickscatter(x,y,z, size=0.5, marker="sphere", opacity=0.2) x,y,z = np.where(islands == 1) ipyvolume.quickscatter(x,y,z, size=0.5, marker="sphere", opacity=0.2, color='blue') # In[ ]: