def __init__(self, parent=None): Qt.QMainWindow.__init__(self, parent) self.frame = Qt.QFrame() self.layout = Qt.QVBoxLayout() self.vtkWidget = QVTKRenderWindowInteractor(self.frame) # Create vedo renderer and add objects and callbacks self.vp = Plotter(qtWidget=self.vtkWidget) self.cbid = self.vp.addCallback("key press", self.onKeypress) self.imgActor = Picture( "https://icatcare.org/app/uploads/2018/07/Helping-your-new-cat-or-kitten-settle-in-1.png" ) self.text2d = Text2D("Use slider to change contrast") self.slider = Qt.QSlider(1) self.slider.valueChanged.connect(self.onSlider) self.layout.addWidget(self.vtkWidget) self.layout.addWidget(self.slider) self.frame.setLayout(self.layout) self.setCentralWidget(self.frame) self.vp.show(self.imgActor, self.text2d, mode='image') # build the vedo rendering self.show() # show the Qt Window
def slicerfunc(index, data): vol = data.mode(1).c('k').alpha(alphas) dims = vol.dimensions() box = vol.box().alpha(0.5) vmin, vmax = vol.scalarRange() msh = vol.zSlice(0).pointColors(cmap=cmaps[index], vmin=vmin, vmax=vmax) sb = msh.lighting('off').addScalarBar3D() zb = vol.zbounds() visibles = [msh] txt = Text2D('..' + data.filename[-30:], font='MonospaceTypewriter') plt.show(vol, msh, sb, box, txt, at=index, interactorStyle=6) def func(widget, event): i = int(widget.GetRepresentation().GetValue()) plt.renderer = widget.GetCurrentRenderer() plt.resetcam = False msh = vol.zSlice(i).lighting('off') msh.pointColors(cmap=cmaps[index], vmin=vmin, vmax=vmax) plt.remove(visibles[0], render=False) if 0 < i < dims[2]: zlev = zb[1] / (zb[1] - zb[0]) * i + zb[0] plt.add([msh, sb.z(zlev)]) visibles[0] = msh return func
def __init__( self, root=True, atlas_name=None, inset=True, title=None, screenshots_folder=None, plotter=None, ): """ Main scene in brainrender. It coordinates what should be render and how should it look like. :param root: bool. If true the brain root mesh is added :param atlas_name: str, name of the brainglobe atlas to be used :param inset: bool. If true an inset is shown with the brain's outline :param title: str. If true a title is added to the top of the window :param screenshots_folder: str, Path. Where the screenshots will be saved """ logger.debug( f"Creating scene with parameters: root: {root}, atlas_name: '{atlas_name}'', inset: {inset}, screenshots_folder: {screenshots_folder}" ) JupyterMixIn.__init__(self) self.actors = [] # stores all actors in the scene self.labels = [] # stores all `labels` actors in scene self.atlas = Atlas(atlas_name=atlas_name) self.screenshots_folder = (Path(screenshots_folder) if screenshots_folder is not None else Path().cwd()) self.screenshots_folder.mkdir(exist_ok=True) # Initialise render class Render.__init__(self, plotter) # Get root mesh self.root = self.add_brain_region( "root", alpha=settings.ROOT_ALPHA, color=settings.ROOT_COLOR, silhouette=True if root and settings.SHADER_STYLE == "cartoon" else False, ) self.atlas.root = self.root # give atlas access to root self._root_mesh = self.root.mesh.clone() if not root: self.remove(self.root) # keep track if we need to make an inset self.inset = inset # add title if title: self.add( Text2D(title, pos="top-center", s=2.5, c="k", alpha=1), names="title", classes="title", )
def __init__( self, root=True, atlas_name=None, inset=True, title=None, screenshots_folder=None, ): """ Main scene in brainrender. It coordinates what should be render and how should it look like. :param root: bool. If true the brain root mesh is added :param atlas_name: str, name of the brainglobe atlas to be used :param inset: bool. If true an inset is shown with the brain's outline :param title: str. If true a title is added to the top of the window :param screenshots_folder: str, Path. Where the screenshots will be saved """ self.actors = [] # stores all actors in the scene self.labels = [] # stores all `labels` actors in scene self.atlas = Atlas(atlas_name=atlas_name) self.screenshots_folder = (Path(screenshots_folder) if screenshots_folder is not None else Path().cwd()) self.screenshots_folder.mkdir(exist_ok=True) # Initialise render class Render.__init__(self) # Get root mesh if root: root_alpha = settings.ROOT_ALPHA else: root_alpha = 0 self.root = self.add_brain_region("root", alpha=root_alpha, color=settings.ROOT_COLOR) self.atlas.root = self.root # give atlas access to root self._root_mesh = self.root.mesh.clone() # keep track if we need to make an inset self.inset = inset # add title if title: self.add( Text2D(title, pos=8, s=2.5, c="k", alpha=1, font="Montserrat"), name="title", br_class="title", ) # keep track if we are in a jupyter notebook if vedo_settings.notebookBackend == "k3d": self.jupyter = True else: self.jupyter = False
def add_text(self, text, pos=8, size=2.5, color="k", alpha=1, font="Montserrat"): """ Adds a 2D text to the scene. Default params are to crate a large black text at the top of the rendering window. :param text: str with text to write :param kwargs: keyword arguments accepted by vedo.shapes.Text2D """ txt = self.add_actor( Text2D(text, pos=pos, s=size, c=color, alpha=alpha, font=font)) return txt
for place, theta, phi, confirmed, deaths, recos in data: pos = spher2cart(1, theta, phi) fl = 'cases: ' + str(confirmed) + '\ndeaths: ' + str(deaths) radius = np.power(confirmed, 1 / 3) / 2000 sph1 = Sphere(pos, radius, alpha=0.4, res=12).flag(place + fl) if deaths > 5000: sph1.flag(fl) anchorpt = sph1.pos() * (1 + radius) vig = sph1.vignette(place, anchorpt, font="Kanopus") vig.c('k').scale(1.5 * (1 + radius)).followCamera() vigs.append(vig) s1.append(sph1) s2.append( Sphere(pos, np.power(deaths, 1 / 3) / 2000, alpha=0.4, c='k', res=10)) tx = Text2D('COVID-19 spread on ' + date + '\n# cases : ' + str(allconf) + '\n# deaths: ' + str(alldeat) + '\n# recovd: ' + str(allreco) + '\n(hover mouse for local info)', font="VictorMono") show(Earth(), s1, merge(s2), vigs, tx, axes=11, bg2='lb', zoom=1.7, elevation=-70, size='fullscreen')
"""Show a cube for each available color name""" print(__doc__) from vedo import Cube, Text2D, show, settings from vedo.colors import colors from operator import itemgetter settings.immediateRendering = False # faster for multi-renderers # sorting by hex color code (matplotlib colors): sorted_colors1 = sorted(colors.items(), key=itemgetter(1)) cbs=[] for sc in sorted_colors1: cname = sc[0] if cname[-1] in "123456789": continue cb = Cube().lw(1).color(cname) tname = Text2D(cname, s=0.9) cbs.append([tname, cb]) print("click on any cube and press i or I") show(cbs, N=len(cbs), azimuth=.2, size='full', title="matplotlib colors", interactive=0) # sort by name (bootstrap5 colors): sorted_colors2 = sorted(colors.items(), key=itemgetter(0)) cbs = [] for sc in sorted_colors2: cname = sc[0] if cname[-1] not in "123456789": continue cb = Cube().lw(1).lighting('off').color(cname) cbs.append([cname, cb]) show(cbs, shape=(11,9), azimuth=.2, size=(800,1000), title="bootstrap5 colors", new=True)
"""Click a sphere to highlight it""" from vedo import Text2D, Sphere, Plotter import numpy as np spheres = [] for i in range(25): p = np.random.rand(2) s = Sphere(r=0.05).pos(p).color('k5') s.name = f"sphere nr.{i} at {p}" spheres.append(s) def func(evt): if not evt.actor: return sil = evt.actor.silhouette().lineWidth(6).c('red5') msg.text("You clicked: " + evt.actor.name) plt.remove(silcont.pop()).add(sil) silcont.append(sil) silcont = [None] msg = Text2D("", pos="bottom-center", c='k', bg='r9', alpha=0.8) plt = Plotter(axes=1, bg='black') plt.addCallback('mouse click', func) plt.show(spheres, msg, __doc__, zoom=1.2).close()
# Font: Glasgo # Font: Normografo # Font: Quikhand # Font: SmartCouric # Font: Theemim # Font: VictorMono # Symbols ~ ^ _ are reserved modifiers: # use ~ to add a short space, 1/4 of the default size, # use ^ and _ to start up/sub scripting, a space terminates them. ################################################################################## 2D for i, f in enumerate(fonts): Text2D( f + ': The quick fox jumps over the lazy dog. 1234567890 αβγδεθλμνπστφψω', pos=(.015, 1 - (i + 3) * .06), font=f, s=1.3, c='k') Text2D("List of Available Fonts", pos='top-center', bg='k', s=1.1) show(..., bg2='cornsilk', axes=False, zoom=1.2, size=(1200, 800), interactive=False) ################################################################################## 3D txt = """The quick fox jumps over the lazy dog. Symbols: !@#$%&*()+=-{}[]:;|<>?/\euro1234567890\~
""" Show a cube for each available texture name. Any jpg file can be used as texture. """ from vedo import Plotter, Cube, Text2D from vedo.settings import textures, textures_path print(__doc__) print('textures_path:', textures_path) print('textures:', textures) vp = Plotter(N=len(textures), axes=0) for i, name in enumerate(textures): if i>30: break cb = Cube().texture(name) tname = Text2D(name, pos=3) vp.show(cb, tname, at=i) vp.show(interactive=1)
def update(evt): global t t += 0.005 P_ = np.zeros((n, 3)) cos_t = 1.5 * np.cos(2 * np.pi * t) sin_t = 1.5 * np.sin(2 * np.pi * t) for i in range(n): x, y = P[i] f = intensity[i] * 50 dx = noise4(scale * x, scale * y, cos_t, sin_t, 2) * f dy = noise4(100 + scale * x, 200 + scale * y, cos_t, sin_t, 2) * f P_[i] = [x + dx, y + dy, np.sqrt(dx * dx + dy * dy) / 2] pts.points(P_) plt.render() pts = Points([X, Y], r=3).alpha(0.8) cir = Circle(pos=(width / 2, height / 2, -5), r=radius * 1.05) txt1 = Text2D("\Lambda L I E N L I F E", s=2.8, pos="top-center") txt2 = Text2D("Original idea by Necessary Disorder", s=0.9, pos="bottom-center") plt = Plotter() plt.show(pts, cir, txt1, txt2, elevation=-35, zoom=1.2, interactive=False) plt.addCallback("timer", update) plt.timerCallback("create") interactive()
# np.random.seed(0) # Generate some noisy data points along a line x = np.linspace(0, 15, 25) a, b = (np.random.rand(2) - 0.5) * 10 # choose a and b y = a * x + b noise = np.random.randn(len(x)) * 5 # create gaussian noise # Plot the points and the "true" line without noise plt = plot(x, y + noise, '*k', title=__doc__) plt += DashedLine(x, y) # Fit points and evaluate, with a boostrap and Monte-Carlo technique, # the correct error coeffs and error bands. Return a Line object: pfit = fit( [x, y + noise], deg=1, # degree of the polynomial niter=500, # nr. of MC iterations to compute error bands nstd=2, # nr. of std deviations to display ) plt += [pfit, pfit.errorBand, *pfit.errorLines] # add these objects to Plot msg = f"Generated a, b : {np.array([a,b])}"\ f"\nFitted a, b : {pfit.coefficients}"\ f"\nerrors on a, b : {pfit.coefficientErrors}"\ f"\nave point spread: \sigma \approx {pfit.dataSigma:.3f} in y units" msg = Text2D(msg, font='VictorMono', pos='bottom-left', c='red3') show(plt, msg, mode="image").close()
'''from vedo import * for i in range(10): Cone().x(i) # no variable assigned! show(...) # show all sofar created objs ''' from vedo import Cone, Text2D, show for i in range(10): Cone().x(2 * i).color(i) # no variable assigned Text2D(__doc__, font='courier') # three points, aka ellipsis, retrieves the list of all created objects show(..., axes=1, viewup='z')
""" Show a cube for each available color name """ print(__doc__) from vedo import Cube, Text2D, show from vedo.colors import colors, getColor from operator import itemgetter # sorting by hex color code: sorted_colors = sorted(colors.items(), key=itemgetter(1)) # or by name: # sorted_colors = sorted(colors.items(), key=itemgetter(0)) cbs = [] for i, sc in enumerate(sorted_colors): cname = sc[0] rgb = getColor(cname) cb = Cube(c=rgb) tname = Text2D(cname, pos=3) cbs.append([tname, cb]) print("click on any cube and press i") show(cbs, N=len(sorted_colors), azimuth=.2, size='fullscreen')
points = Points(cpoints).c('violet') spline = None if len(cpoints) > 1: spline = KSpline(cpoints).c('yellow').alpha(0.5) plt.add([spline, points]) def keyfunc(key): global spline, points, cpoints if key == 'c': plt.remove([spline, points]) cpoints, points, spline = [], None, None ############################################################################## plt = Plotter() plt.keyPressFunction = keyfunc plt.mouseLeftClickFunction = onLeftClick plt.mouseRightClickFunction = onRightClick t = """Click to add a point Right-click to remove it Press c to clear points""" msg = Text2D(t, pos="bottom-left", c='k', bg='green', font='Quikhand', s=0.9) pic = plt.load(datadir + "images/dog.jpg") # make a transparent box around the picture for clicking box = pic.box(pad=1).wireframe(False).alpha(0.01) plt.show(__doc__, pic, box, msg, axes=True, interactorStyle=6, bg='w')
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() plt.render() plt = Plotter(size=(2200,1100), title="Earthquake Browser") plt.addSlider2D(sliderfunc, 0, len(centers)-1, value=len(centers)-1, showValue=False, title="today") plt.addHoverLegend(useInfo=True, alpha=1, c='white', bg='red2', s=1) comment = Text2D(__doc__, bg='green9', alpha=0.7) plt.show(pic, centers, comment, zoom=2.27, mode='image').close()