def viz_mean_excitability(sid, rid): regpos, w, obsmask, surfaces, contacts = read_structural_data(sid, rid) vlines, vmeshes, vcontacts = viz_structure(regpos, w, surfaces, contacts) # Load results nreg = regpos.shape[0] res = io.parse_csv([ f"run/solo/INC/vep/id{sid:03d}/output/r{rid:02d}_all/chain_{chain}.csv" for chain in [1, 2] ]) cinf = res['c'] # cmean = np.mean(cinf, axis=0) # pexc = np.mean(cinf > 2.0, axis=0) scalar = np.percentile(cinf, 50, axis=0) # Regions cmap = 'plasma' # vmin = np.min(scalar) # vmax = np.max(scalar) vmin, vmax = -2, 2 vpoints = [] for i in range(nreg): if not obsmask[i]: vpoints.append( vp.Sphere(regpos[i], r=4, c=vp.colorMap(scalar[i], cmap, vmin, vmax))) else: vpoints.append( vp.Cube(regpos[i], side=6, c=vp.colorMap(scalar[i], cmap, vmin, vmax))) vbar = vp.Points(regpos, r=0.01).pointColors(scalar, cmap=cmap, vmin=vmin, vmax=vmax) vbar.addScalarBar(horizontal=True, pos=(0.8, 0.02)) def slider(widget, event): percentile = widget.GetRepresentation().GetValue() scalar = np.percentile(cinf, percentile, axis=0) for i in range(nreg): vpoints[i].color(vp.colorMap(scalar[i], cmap, vmin, vmax)) vplotter = vp.Plotter(axes=0) vplotter.addSlider2D(slider, 0., 100., value=50.0, pos=3, title="Percentile") vplotter.show(vpoints, vlines, vmeshes, vcontacts, vbar)
def viz_network_scalar(centres, scalars, weights, obsmask, surfs, view='topdown', size=(1000, 1000), cmap='viridis', vmin=None, vmax=None): vp.embedWindow(False) if vmin is None: vmin = np.min(scalars) if vmax is None: vmax = np.max(scalars) vlines, vmeshes = viz_structure(centres, weights, surfs, w_perc=3) nreg = centres.shape[0] # Regions vpoints = [] for i in range(nreg): if not obsmask[i]: vpoints.append( vp.Sphere(centres[i], r=4, c=vp.colorMap(scalars[i], cmap, vmin, vmax))) else: vpoints.append( vp.Cube(centres[i], side=6, c=vp.colorMap(scalars[i], cmap, vmin, vmax))) if view == 'topdown': args = dict(elevation=0, azimuth=0, roll=0, zoom=1.4) elif view == 'leftright': args = dict(elevation=0, azimuth=270, roll=90, zoom=1.4) elif view == 'rightleft': args = dict(elevation=0, azimuth=90, roll=270, zoom=1.4) else: raise ValueError(f"Unexpected view: {view}") vplotter = vp.Plotter(axes=0, offscreen=True, size=size) vplotter.show(vpoints, vlines, vmeshes, N=1, **args) img = vp.screenshot(None, scale=1, returnNumpy=True) vp.clear() vp.closePlotter() return img
def viz_excitability(sid, rid): regpos, w, obsmask, surfaces, contacts = read_structural_data(sid, rid) vlines, vmeshes, vcontacts = viz_structure(regpos, w, surfaces, contacts) # Load results nreg = regpos.shape[0] res = io.parse_csv([ f"run/solo/INC/vep/id{sid:03d}/output/r{rid:02d}_all/chain_{chain}.csv" for chain in [1, 2] ]) cinf = res['c'] ctr = 2.0 pexc = np.mean(cinf > ctr, axis=0) # Regions cmap = 'Reds' vmin, vmax = 0, 0.15 # vmin, vmax = -2, 0 vpoints = [] for i in range(nreg): if not obsmask[i]: vpoints.append( vp.Sphere(regpos[i], r=4, c=vp.colorMap(pexc[i], cmap, vmin, vmax))) else: vpoints.append( vp.Cube(regpos[i], side=6, c=vp.colorMap(pexc[i], cmap, vmin, vmax))) vbar = vp.Points(regpos, r=0.01).pointColors(pexc, cmap=cmap, vmin=vmin, vmax=vmax) vbar.addScalarBar(horizontal=True, pos=(0.8, 0.02)) def cslider(widget, event): ctr = widget.GetRepresentation().GetValue() pexc = np.mean(cinf > ctr, axis=0) for i in range(nreg): vpoints[i].color(vp.colorMap(pexc[i], cmap, vmin, vmax)) vplotter = vp.Plotter(axes=0) vplotter.addSlider2D(cslider, -3.0, 3.0, value=2.0, pos=3, title="c") vplotter.show(vpoints, vlines, vmeshes, vcontacts, vbar)
def video_timestep(vplotter, video, vpoints, vtext, vobjects, tfrom, tto, nframes, tinf, cmap, cam): print("Run...") for t in np.linspace(tfrom, tto, nframes): pszs = np.mean(tinf < t, axis=0) for vpoint, psz in zip(vpoints, pszs): vpoint.color(vp.colorMap(psz, cmap, 0, 1)) # vtext.SetText(1, f"t = {t:4.1f} s") # vtext.SetNonlinearFontScaleFactor(2.0/2.7) # Recreate vtext # print(vtext.s) # vplotter.remove(vtext) # vtext = vp.Text2D(f"t = {t:4.1f} s", pos=(0.1, 0.1), s=3, c='black') # vtext = vp.Text2D(f"t = {t:4.1f} s", pos=(0.1, 0.1), s=3, c='black') # vplotter.show(vpoints, vtext, *vobjects, camera={'pos':cam['pos'], 'focalPoint':cam['focalPoint'], 'viewup':cam['viewup']}) # vplotter.clear() # vplotter.show(vpoints, vtext, *vobjects, camera={'pos':cam['pos'], 'focalPoint':cam['focalPoint'], 'viewup':cam['viewup']}) vtext = vp.Text2D(f"t = {t:4.1f} s", (10, 10), s=6, c='black') vplotter += vtext vplotter.show( camera={ 'pos': cam['pos'], 'focalPoint': cam['focalPoint'], 'viewup': cam['viewup'] }) video.addFrame() vplotter -= vtext
def viz_seizure(sid, rid): regpos, w, obsmask, surfaces, contacts = read_structural_data(sid, rid) vlines, vmeshes, vcontacts = viz_structure(regpos, w, surfaces, contacts) # Load results nreg = regpos.shape[0] res = io.parse_csv([ f"run/solo/INC/vep/id{sid:03d}/output/r{rid:02d}_all/chain_{chain}.csv" for chain in [1, 2] ]) tinf = res['t'] t = 0.0 psz = np.mean(tinf < t, axis=0) # Regions cmap = 'bwr' vmin, vmax = 0, 1 vpoints = [] for i in range(nreg): if not obsmask[i]: vpoints.append( vp.Sphere(regpos[i], r=4, c=vp.colorMap(psz[i], cmap, vmin, vmax))) else: vpoints.append( vp.Cube(regpos[i], side=6, c=vp.colorMap(psz[i], cmap, vmin, vmax))) vbar = vp.Points(regpos, r=0.01).pointColors(psz, cmap=cmap, vmin=vmin, vmax=vmax) vbar.addScalarBar(horizontal=True, pos=(0.8, 0.02)) def tslider(widget, event): t = widget.GetRepresentation().GetValue() psz = np.mean(tinf < t, axis=0) for i in range(nreg): vpoints[i].color(vp.colorMap(psz[i], cmap, vmin, vmax)) vplotter = vp.Plotter(axes=0) vplotter.addSlider2D(tslider, 0, 90.0, value=0.0, pos=3, title="t") vplotter.show(vpoints, vlines, vmeshes, vcontacts, vbar)
def get_color_map(controller, scalar_map, nan_color=[0.0, 0.0, 0.0], nan_alpha=1.0): """ Get a color map :param controller: IBLViewer.AtlasController :param scalar_map: Dictionary that maps scalar values in the dictionary to your custom values :param nan_color: Default color for unspecified values :param nan_alpha: Default alpha for unspecified values :param seed: Random seed to fake a time series :return: Color map and alpha map """ rgb = [] alpha = [] # Init all to clear gray (90% white) #c = np.ones((self.metadata.id.size, 4)).astype(np.float32) * 0.9 #c[:, -1] = 0.0 if only_custom_data else alpha_factor #print('Assigning', values.size, 'to atlas ids', self.metadata.id.size) for r_id in range(len(controller.model.metadata)): rgb.append([r_id, nan_color]) a = nan_alpha if r_id > 0 else 0.0 alpha.append([r_id, a]) values = scalar_map.values() min_p = min(values) max_p = max(values) rng_p = max_p - min_p """ # Another way to compute colors with matplotlib cm. You will need to import matplotlib norm = matplotlib.colors.Normalize(vmin=min_p, vmax=max_p, clip=True) mapper = matplotlib.cm.ScalarMappable(norm=norm, cmap=cm.viridis) """ for row_id in scalar_map: value = scalar_map[row_id] """ # Another way to compute colors with matplotlib cm # (yields the same result as vedo, except you get alpha on top) r, g, b, a = mapper.to_rgba(value) rgb[row_id] = [row_id, [r, g, b]] """ rgb[row_id] = [ row_id, list(vedo.colorMap(value, 'viridis', min_p, max_p)) ] alpha[row_id] = [row_id, 1.0] return rgb, alpha
def get_color_map(controller, scalar_map, color_map_func='viridis', nan_color=[0.0, 0.0, 0.0], nan_alpha=0.0, seed=None): """ Generate a color map with the scalar map. Simply put, we assign colors to the values. """ if seed is not None: random.seed(seed) rgb = [] alpha = [] for r_id in range(controller.model.atlas.regions.id.size): rand_val = np.random.uniform(0, 0.35) rgb.append([r_id, np.array([rand_val] * 3) + nan_color]) a = nan_alpha if r_id > 0 else 0.0 alpha.append([r_id, a]) values = sorted(scalar_map.values()) min_p = min(values) max_p = max(values) rng_p = max_p - min_p #cmap = vedo.colorMap(values, cmap_name, min_p, max_p) for row_id in scalar_map: value = scalar_map[row_id] if seed is not None and seed > 0: value = value + random.random() * rng_p / 2 #rgb[row_id] = [row_id, list(vedo.colorMap(value, cmap_name, min_p, max_p))] if isinstance(color_map_func, str): rgb[row_id][1] = list( vedo.colorMap(value, color_map_func, min_p, max_p)) else: # Here we assume you provided a function that is called with these values rgb[row_id][1] = color_map_func(value, min_p, max_p) alpha[row_id] = [row_id, 1.0] return rgb, alpha
def animate(vplotter, video, nframes, vpoints, tinf, prange=(0., 1.), time=0.0, pos=(1, 0, 0), foc=(0, 0, 0), viewup=(0, 1, 0), startpoint=True, endpoint=True): cmap = 'bwr' if startpoint and endpoint: params = np.linspace(prange[0], prange[1], nframes) elif startpoint and not endpoint: params = np.linspace(prange[0], prange[1], nframes + 1)[:-1] elif not startpoint and endpoint: params = np.linspace(prange[0], prange[1], nframes + 1)[1:] else: params = np.linspace(prange[0], prange[1], nframes + 2)[1:-1] for param in params: p = pos if not callable(pos) else pos(param) f = foc if not callable(foc) else foc(param) v = viewup if not callable(viewup) else viewup(param) t = time if not callable(time) else time(param) pszs = np.mean(tinf < t, axis=0) for vpoint, psz in zip(vpoints, pszs): vpoint.color(vp.colorMap(psz, cmap, 0, 1)) vtext = vp.Text2D(f"t = {t:4.1f} s", (10, 10), s=6, c='black') vplotter += vtext vplotter.show(camera=dict(pos=p, focalpoint=f, viewup=v)) video.addFrame() vplotter -= vtext
# A plot(mode="bars") example. Useful to plot categories. from vedo import precision, Text3D, colorMap, settings from vedo.pyplot import plot settings.defaultFont = "Meson" counts = [1946, 8993, 3042, 1190, 1477, 0, 0] percent = [11.68909178, 54.01850072, 18.27246516, 7.14800577, 8.87193657, 0, 0] labels = [ '<100', '100-250', '250-500', '500-750', '750-1000', '1000-2000', '>2000' ] colors = colorMap(range(len(counts)), "hot") plt = plot( [counts, labels, colors], mode="bars", ylim=(0, 10500), aspect=4 / 3, axes=dict( htitle="Clusters in lux range", hTitleItalic=False, xLabelRotation=35, xLabelSize=0.02, tipSize=0, # axes arrow tip size ), ) for i in range(len(percent)): val = precision(percent[i], 3) + '%' txt = Text3D(val, pos=(plt.centers[i], counts[i]),
"""Elliptic Fourier Descriptors parametrizing a closed countour (in red)""" import vedo, pyefd shapes = vedo.load(vedo.dataurl+'timecourse1d.npy') sh = shapes[55] sr = vedo.Line(sh).mirror('x').reverse() sm = vedo.merge(sh, sr).c('red5').lw(3) pts = sm.points()[:,(0,1)] rlines = [] for order in range(5,30, 5): coeffs = pyefd.elliptic_fourier_descriptors(pts, order=order, normalize=False) a0, c0 = pyefd.calculate_dc_coefficients(pts) rpts = pyefd.reconstruct_contour(coeffs, locus=(a0,c0), num_points=400) color = vedo.colorMap(order, "Blues", 5,30) rline = vedo.Line(rpts).lw(3).c(color) rlines.append(rline) sm.z(0.1) # move it on top so it's visible vedo.show(sm, *rlines, __doc__, axes=1, bg='k', size=(1190, 630), zoom=1.8)
continue if row_id == 0: #or value.isnull().values.any(): # We ignore void acronym and nan values continue scalars_map[int(row_id)] = value rgb = [] alpha = [] for r_id in range(controller.model.atlas.regions.id.size): rand_val = np.random.uniform(0, 0.35) rgb.append([r_id, np.array([rand_val] * 3) + nan_color]) a = nan_alpha if r_id > 0 else 0.0 alpha.append([r_id, a]) values = sorted(scalars_map.values()) min_p = VMIN max_p = VMAX rng_p = max_p - min_p #cmap = vedo.colorMap(values, cmap_name, min_p, max_p) for row_id in scalars_map: value = scalars_map[row_id] rgb[row_id][1] = list(vedo.colorMap(value, COLOR_MAP, min_p, max_p)) alpha[row_id] = [row_id, 1.0] controller.add_transfer_function(scalars_map, rgb, alpha, COLOR_MAP, make_current=False) controller.render()
def tslider(widget, event): t = widget.GetRepresentation().GetValue() psz = np.mean(tinf < t, axis=0) for i in range(nreg): vpoints[i].color(vp.colorMap(psz[i], cmap, vmin, vmax))
def make_video(sid, rid, video_file): regpos, w, obsmask, surfaces, contacts = read_structural_data(sid, rid) vlines, vmeshes, vcontacts = viz_structure(regpos, w, surfaces, contacts) # Load results res = io.parse_csv([ f"run/solo/INC/vep/id{sid:03d}/output/r{rid:02d}_all/chain_{chain}.csv" for chain in [1, 2] ]) tinf = res['t'] t = 0.0 psz = np.mean(tinf < t, axis=0) nreg = regpos.shape[0] # Regions cmap = 'bwr' vpoints = [] for i in range(nreg): if not obsmask[i]: vpoints.append( vp.Sphere(regpos[i], r=4, c=vp.colorMap(psz[i], cmap, 0, 1))) else: vpoints.append( vp.Cube(regpos[i], side=6, c=vp.colorMap(psz[i], cmap, 0, 1))) vbar = vp.Points(regpos, r=0.01).pointColors(psz, cmap=cmap, vmin=0, vmax=1) vbar.addScalarBar(horizontal=True, pos=(0.8, 0.02)) vtext = vp.Text2D(f"t = {t:4.1f} s", pos=0, s=2, c='black') center = np.mean(regpos, axis=0) dist = 2.5 * (np.max(regpos[:, 1]) - np.min(regpos[:, 1])) # Video ------------------------------------------------------- vplotter = vp.Plotter(axes=0, interactive=0, offscreen=True, size=(1800, 1800)) nframes = 3000 vplotter += vpoints vplotter += vlines vplotter += vmeshes video = vp.Video(name=video_file, duration=90) ratios = np.array([30, 3, 5, 30, 5, 3, 30, 10]) frames = (nframes * ratios / np.sum(ratios)).astype(int) # Run and pause animate(vplotter, video, frames[0], vpoints, tinf, pos=center + dist * np.r_[0, 0, 1], foc=center, viewup=(0, 1, 1), prange=(0, 45), time=lambda p: p) animate(vplotter, video, frames[1], vpoints, tinf, pos=center + dist * np.r_[0, 0, 1], foc=center, viewup=(0, 1, 1), time=45.) ## Fly around pos = lambda angle: center + dist * np.array( [0, -np.sin(angle), np.cos(angle)]) animate(vplotter, video, frames[2], vpoints, tinf, pos=pos, foc=center, viewup=(0, 1, 1), prange=(0, np.pi / 2), time=45., endpoint=False) pos = lambda angle: center + dist * np.array( [-np.sin(angle), -np.cos(angle), 0]) animate(vplotter, video, frames[3], vpoints, tinf, pos=pos, foc=center, viewup=(0, 0, 1), prange=(0, 2 * np.pi), time=45.) pos = lambda angle: center + dist * np.array( [0, -np.sin(angle), np.cos(angle)]) animate(vplotter, video, frames[4], vpoints, tinf, pos=pos, foc=center, viewup=(0, 1, 1), prange=(np.pi / 2, 0), time=45., startpoint=False) # Pause + run + pause animate(vplotter, video, frames[5], vpoints, tinf, pos=center + dist * np.r_[0, 0, 1], foc=center, viewup=(0, 1, 1), time=45.) animate(vplotter, video, frames[6], vpoints, tinf, pos=center + dist * np.r_[0, 0, 1], foc=center, viewup=(0, 1, 1), prange=(45, 90), time=lambda p: p) animate(vplotter, video, frames[7], vpoints, tinf, pos=center + dist * np.r_[0, 0, 1], foc=center, viewup=(0, 1, 1), time=90.) video.close()
def cslider(widget, event): ctr = widget.GetRepresentation().GetValue() pexc = np.mean(cinf > ctr, axis=0) for i in range(nreg): vpoints[i].color(vp.colorMap(pexc[i], cmap, vmin, vmax))
def slider(widget, event): percentile = widget.GetRepresentation().GetValue() scalar = np.percentile(cinf, percentile, axis=0) for i in range(nreg): vpoints[i].color(vp.colorMap(scalar[i], cmap, vmin, vmax))
sinr, cosr = np.sin(r), np.cos(r) sinlat, coslat = np.sin(lat), np.cos(lat) for phi in np.linspace(0, 2*np.pi, num=res, endpoint=False): clat = np.arcsin(sinlat * cosr + coslat * sinr * np.cos(phi)) clng = lon + np.arctan2(np.sin(phi) * sinr * coslat, cosr - sinlat * np.sin(clat)) coords.append([clng/np.pi + 1, clat*2/np.pi + 1, 0]) return Polygon(nsides=res).points(coords) # warp polygon points to match geo projection centers = [] pb = ProgressBar(0, len(data)) for i, d in data.iterrows(): pb.print("Parsing USGS data..") M = d['mag'] # earthquake estimated magnitude E = np.sqrt(np.exp(5.24+1.44*M) * scale[0])/10000 # empirical formula for sqrt(energy_release(M)) rgb = colorMap(E, name='Reds', vmin=0, vmax=7) # map energy to color lat, lon = np.deg2rad(d['latitude']), np.deg2rad(d['longitude']) ce = GeoCircle(lat, lon, E/50).scale(scale).z(num/M).c(rgb).lw(0.1).useBounds(False) ce.time = i ce.info = '\n'.join(str(d).split('\n')[:-1]) # remove of the last line in string d #if M > 6.5: ce.alpha(0.8) # make the big ones slightly transparent if i < len(data)-num: ce.off() # switch off older ones: make circles invisible centers.append(ce) def sliderfunc(widget, event): value = widget.GetRepresentation().GetValue() # get the slider current value widget.GetRepresentation().SetTitleText(f"{data['time'][int(value)][:10]}") for ce in centers: isinside = abs(value-ce.time) < num # switch on if inside of time window ce.on() if isinside else ce.off()