def show_ipygany(plotter, return_viewer, height=None, width=None): """Show an ipygany scene.""" # convert each mesh in the plotter to an ipygany scene actors = plotter.renderer._actors meshes = [] for actor in actors.values(): ipygany_obj = ipygany_block_from_actor(actor) if ipygany_obj is not None: meshes.append(ipygany_obj) bc_color = color_float_to_hex(*plotter.background_color) scene = Scene(meshes, background_color=bc_color, camera=ipygany_camera_from_plotter(plotter)) # optionally size of the plotter if height is not None: scene.layout.height = f'{height}' if width is not None: scene.layout.width = f'{width}' cbar = None if len(plotter.scalar_bars): for mesh in meshes: if isinstance(mesh, ipygany.IsoColor): cbar = ipygany.ColorBar(mesh) colored_mesh = mesh break # Simply return the scene if return_viewer: return scene if cbar is not None: # Colormap choice widget colormap_dd = Dropdown(options=colormaps, description='Colormap:') jslink((colored_mesh, 'colormap'), (colormap_dd, 'index')) # sensible colorbar maximum width, or else it looks bad when # window is large. cbar.layout.max_width = '500px' cbar.layout.min_height = '50px' # stop from getting squished # cbar.layout.height = '20%' # stop from getting squished # cbar.layout.max_height = '' # Create a slider that will dynamically change the boundaries of the colormap # colormap_slider_range = FloatRangeSlider(value=[height_min, height_max], # min=height_min, max=height_max, # step=(height_max - height_min) / 100.) # jslink((colored_mesh, 'range'), (colormap_slider_range, 'value')) # create app title = HTML(value=f'<h3>{list(plotter.scalar_bars.keys())[0]}</h3>') legend = VBox((title, colormap_dd, cbar)) scene = AppLayout(center=scene, footer=legend, pane_heights=[0, 0, '150px']) display.display_html(scene)
def create_layout(self): # timer.display_timer(5) layout = AppLayout( # header=header_button, header=self.timer_button, left_sidebar=None, center=self.center_button, right_sidebar=None, footer=self.footer_button) self.layout = layout return layout
def area(): """ Provide map and options to choose area of interest """ center = [65.73, -50.71] zoom = 4 m = Map(center=center, zoom=zoom) global dc, start, end, file, lon_l, lat_l, lon_r, lat_r # Pick date start = widgets.DatePicker(disabled=False) end = widgets.DatePicker(disabled=False) # Select from map dc = DrawControl(rectangle={'shapeOptions': { 'color': '#0000FF' }}, polyline={}, polygon={}, circlemarker={}) m.add_control(dc) # Shapefile file = widgets.FileUpload(accept='.shp', multiple=False) # Bounding box lon_l = widgets.FloatText(description="lon") lat_l = widgets.FloatText(description="lat") lon_r = widgets.FloatText(description="lon") lat_r = widgets.FloatText(description="lat") return (AppLayout(header=VBox([ HTML("<h1>Select area (time and space)</h1>"), HBox([Label("Start Date:"), start, Label("End Date:"), end]) ]), center=m, right_sidebar=VBox([ HTML("<h3>or upload shapefile<h3>"), file, HTML("<h3> <h3>"), HTML("<h3>or bounding box<h3>"), Label("Bottom-left corner"), lon_l, lat_l, Label("Upper-right corner"), lon_r, lat_r ])))
def hoodflex_widget(self): one_year = list( [self.start + dt.timedelta(days=i) for i in range(364)]) tick_options = [(one_year[i].strftime('%m/%d/%Y'), i / 12) for i in range(len(one_year)) if i % 6 == 0] date_slider = SelectionRangeSlider(options=tick_options, index=(30, 60), description='Date:', disabled=False) date_slider.layout.margin = '0px 30% 0px 30%' date_slider.layout.width = '40%' self.plot_setup() self.full_plot() date_slider.observe(self.update_plot, names='value') date_slider.observe(self.update_plot, names='label') app_layout = AppLayout(center=self.fig.canvas, footer=date_slider, pane_heights=[0, 6, 1]) return app_layout
colored_mesh = IsoColor(mesh, input=('S', 'YY'), min=sigmayy_min, max=sigmayy_max) # Create a slider that will dynamically change the boundaries of the colormap colormap_slider_range = FloatRangeSlider(value=[sigmayy_min, sigmayy_max], min=sigmayy_min, max=sigmayy_max, step=(sigmayy_max - sigmayy_min) / 100.) jslink((colored_mesh, 'range'), (colormap_slider_range, 'value')) # Create a colorbar widget colorbar = ColorBar(colored_mesh) # Colormap choice widget colormap = Dropdown(options=colormaps, description='colormap:') jslink((colored_mesh, 'colormap'), (colormap, 'index')) AppLayout( header=Scene([colored_mesh]), left_sidebar=VBox((colormap, colormap_slider_range)), right_sidebar=(colorbar), pane_widths=[1, 0, 1], pane_heights=['80%', '20%', 0], footer=None, )
def docking( protein_filepath, list_docking_poses_filepaths, list_docking_poses_labels, list_docking_poses_affinities, ): """ Visualize a list of docking poses in the protein structure, using NGLView. Parameters ---------- protein_filepath : str or pathlib.Path Filepath of the extracted protein structure used in docking experiment. list_docking_poses_filepaths : list of str or pathlib.Path List of filepaths for the separated docking poses. list_docking_poses_labels : list of str List of labels for docking poses to be used for the selection menu. list_docking_poses_affinities : list of str or float List of binding affinities in kcal/mol, to be viewed for each docking pose. Returns ------- nglview.widget.NGLWidget Interactive viewer containing the protein structure and all docking poses, with a menu to select between docking poses. """ # JavaScript code needed to update residues around the ligand # because this part is not exposed in the Python widget # Based on: http://nglviewer.org/ngl/api/manual/snippets.html _RESIDUES_AROUND = """ var protein = this.stage.compList[0]; var ligand_center = this.stage.compList[{index}].structure.atomCenter(); var around = protein.structure.getAtomSetWithinPoint(ligand_center, {radius}); var around_complete = protein.structure.getAtomSetWithinGroup(around); var last_repr = protein.reprList[protein.reprList.length-1]; protein.removeRepresentation(last_repr); protein.addRepresentation("licorice", {{sele: around_complete.toSeleString()}}); """ print("Docking modes") print("(CID - mode)") # Create viewer widget viewer = nv.NGLWidget(height="860px") protein_filepath = Path(protein_filepath) with open(protein_filepath) as f: viewer.add_component(f, ext=protein_filepath.suffix.strip(".")) # Select first atom in molecule (@0) so it holds the affinity label label_kwargs = dict( labelType="text", sele="@0", showBackground=True, backgroundColor="black", ) list_docking_poses_affinities = list( map(lambda x: f"{x} kcal/mol", list_docking_poses_affinities)) for docking_pose_filepath, ligand_label in zip( list_docking_poses_filepaths, list_docking_poses_affinities): docking_pose_filepath = Path(docking_pose_filepath) with open(docking_pose_filepath) as f: ngl_ligand = viewer.add_component( f, ext=docking_pose_filepath.suffix.strip(".")) ngl_ligand.add_label(labelText=[str(ligand_label)], **label_kwargs) # Create selection widget # Options is a list of (text, value) tuples. When we click on select, the value will be passed # to the callable registered in `.observe(...)` selector = Select( options=[(label, i) for (i, label) in enumerate(list_docking_poses_labels, 1)], description="", # the chosen height for the viewer corresponds to a menu with 52 items. # if there are less than 52 items in the menu, fit the menu height to the items, # if there are more than 52 items, create a scroll menu with a height of 52 items. rows=len(list_docking_poses_filepaths) if len(list_docking_poses_filepaths) <= 52 else 52, layout=Layout(flex="flex-grow", width="auto"), ) # Arrange GUI elements # The selection box will be on the left, the viewer will occupy the rest of the window display( AppLayout(left_sidebar=selector, center=viewer, pane_widths=[1, 6, 1])) # This is the event handler - action taken when the user clicks on the selection box # We need to define it here so it can "see" the viewer variable def _on_selection_change(change): # Update only if the user clicked on a different entry if change["name"] == "value" and (change["new"] != change["old"]): viewer.hide(list(range(1, len(list_docking_poses_filepaths) + 1))) # Hide all ligands (components 1-n) component = getattr(viewer, f"component_{change['new']}") component.show() # Display the selected one component.center(500) # Zoom view # Call the JS code to show sidechains around ligand viewer._execute_js_code( _RESIDUES_AROUND.format(index=change["new"], radius=6)) # Register event handler selector.observe(_on_selection_change) # Trigger event manually to focus on the first solution _on_selection_change({"name": "value", "new": 1, "old": None}) return viewer
def interactions( protein_filepath, list_docking_poses_filepaths, list_docking_poses_labels, list_docking_poses_affinities, list_docking_poses_plip_dicts, ): """ Visualize protein-ligand interactions. Parameters ---------- protein_filepath : str or pathlib.Path Filepath of the extracted protein structure used in docking experiment. list_docking_poses_filepaths : list of str or pathlib.Path List of filepaths for the separated docking poses. list_docking_poses_labels : list of str List of labels for docking poses to be used for the selection menu. list_docking_poses_affinities : list of str or float List of binding affinities in kcal/mol, to be viewed for each docking pose. list_docking_poses_plip_dicts : list of dicts List of interaction data (as a dict) for each ligand, generated by plip. Returns ------- nglview.widget.NGLWidget Interactive viewer containing the protein structure, all docking poses, and the interactions between them, with a menu to select between docking poses. """ color_map = { "hydrophobic": [0.90, 0.10, 0.29], "hbond": [0.26, 0.83, 0.96], "waterbridge": [1.00, 0.88, 0.10], "saltbridge": [0.67, 1.00, 0.76], "pistacking": [0.75, 0.94, 0.27], "pication": [0.27, 0.60, 0.56], "halogen": [0.94, 0.20, 0.90], "metal": [0.90, 0.75, 1.00], } # Create selection widget # Options is a list of (text, value) tuples. # When we click on select, the value will be passed # to the callable registered in `.observe(...)` selector = Select( options=[(label, i) for (i, label) in enumerate(list_docking_poses_labels, 1)], description="", # the chosen height for the viewer corresponds to a menu with 52 items. # if there are less than 52 items in the menu, fit the menu height to the items, # if there are more than 52 items, create a scroll menu with a height of 52 items. rows=len(list_docking_poses_filepaths) if len(list_docking_poses_filepaths) <= 52 else 52, layout=Layout(flex="flex-grow", width="auto"), ) # Arrange GUI elements # The selection box will be on the left, # the viewer will occupy the rest of the window (but it will be added later) app = AppLayout( left_sidebar=selector, center=None, pane_widths=[1, 6, 1], height="860px", ) # Show color-map fig, axs = plt.subplots(nrows=2, ncols=4, figsize=(12, 1)) plt.subplots_adjust(hspace=1) fig.suptitle("Color-map of interactions", size=10, y=1.3) for ax, (interaction, color) in zip(fig.axes, color_map.items()): ax.imshow(np.zeros((1, 5)), cmap=colors.ListedColormap(color_map[interaction])) ax.set_title(interaction, loc="center", fontsize=10) ax.set_axis_off() plt.show() list_docking_poses_affinities = list( map(lambda x: f"{x} kcal/mol", list_docking_poses_affinities)) protein_filepath = Path(protein_filepath) # This is the event handler - action taken when the user clicks on the selection box # We need to define it here so it can "see" the viewer variable def _on_selection_change(change): # Update only if the user clicked on a different entry if change["name"] == "value" and (change["new"] != change["old"]): if app.center is not None: app.center.close() # NGL Viewer app.center = viewer = nv.NGLWidget(height="860px", default=True, gui=True) with open(protein_filepath) as f: prot_component = viewer.add_component( f, ext=protein_filepath.suffix.strip("."), default_representation=False) # add protein prot_component.add_representation("cartoon") time.sleep(1) label_kwargs = dict( labelType="text", sele="@0", showBackground=True, backgroundColor="black", ) list_docking_poses_filepaths[change["new"]] = Path( list_docking_poses_filepaths[change["new"]]) with open(list_docking_poses_filepaths[change["new"]]) as f: lig_component = viewer.add_component( f, ext=list_docking_poses_filepaths[change["new"]].suffix. strip(".")) # add selected ligand lig_component.add_label( labelText=[str(list_docking_poses_affinities[change["new"]])], **label_kwargs) time.sleep(1) lig_component.center(duration=500) # Add interactions interactions = list_docking_poses_plip_dicts[change["new"]] interacting_residues = [] for interaction_type, interaction_list in interactions.items(): color = color_map[interaction_type] # for each interaction_type the interaction_list starts with a tuple # containing the keywords for that interaction. If the list has only this # one element, it means there is no interaction of this type available, # so we skip the rest of the loop and go to the next interaction. if len(interaction_list) == 1: continue df_interactions = pd.DataFrame.from_records( interaction_list[1:], columns=interaction_list[0]) for _, interaction in df_interactions.iterrows(): name = interaction_type viewer.shape.add_cylinder( interaction["LIGCOO"], interaction["PROTCOO"], color, [0.1], name, ) interacting_residues.append(interaction["RESNR"]) # Display interacting residues res_sele = " or ".join( [f"({r} and not _H)" for r in interacting_residues]) res_sele_nc = " or ".join([ f"({r} and ((_O) or (_N) or (_S)))" for r in interacting_residues ]) prot_component.add_ball_and_stick(sele=res_sele, colorScheme="chainindex", aspectRatio=1.5) prot_component.add_ball_and_stick(sele=res_sele_nc, colorScheme="element", aspectRatio=1.5) # Register event handler selector.observe(_on_selection_change) # Trigger event manually to focus on the first solution _on_selection_change({"name": "value", "new": 0, "old": None}) return app
def getNotebookBackend(actors2show, zoom, viewup): vp = settings.plotter_instance if zoom == 'tight': zoom=1 # disable it if isinstance(vp.shape, str) or sum(vp.shape) > 2: colors.printc("Multirendering is not supported in jupyter.", c=1) return #################################################################################### # https://github.com/InsightSoftwareConsortium/itkwidgets # /blob/master/itkwidgets/widget_viewer.py if 'itk' in settings.notebookBackend: from itkwidgets import view settings.notebook_plotter = view(actors=actors2show, cmap='jet', ui_collapsed=True, gradient_opacity=False) #################################################################################### elif settings.notebookBackend == 'k3d': try: import k3d # https://github.com/K3D-tools/K3D-jupyter except: print("Cannot find k3d, install with: pip install k3d") return actors2show2 = [] for ia in actors2show: if not ia: continue if isinstance(ia, vtk.vtkAssembly): #unpack assemblies acass = ia.unpack() actors2show2 += acass else: actors2show2.append(ia) # vbb, sizes, _, _ = addons.computeVisibleBounds() # kgrid = vbb[0], vbb[2], vbb[4], vbb[1], vbb[3], vbb[5] settings.notebook_plotter = k3d.plot(axes=[vp.xtitle, vp.ytitle, vp.ztitle], menu_visibility=settings.k3dMenuVisibility, height=settings.k3dPlotHeight, antialias=settings.k3dAntialias, ) # settings.notebook_plotter.grid = kgrid settings.notebook_plotter.lighting = settings.k3dLighting # set k3d camera settings.notebook_plotter.camera_auto_fit = settings.k3dCameraAutoFit settings.notebook_plotter.grid_auto_fit = settings.k3dGridAutoFit settings.notebook_plotter.axes_helper = settings.k3dAxesHelper if settings.plotter_instance and settings.plotter_instance.camera: k3dc = utils.vtkCameraToK3D(settings.plotter_instance.camera) if zoom: k3dc[0] /= zoom k3dc[1] /= zoom k3dc[2] /= zoom settings.notebook_plotter.camera = k3dc # else: # vsx, vsy, vsz = vbb[0]-vbb[1], vbb[2]-vbb[3], vbb[4]-vbb[5] # vss = numpy.linalg.norm([vsx, vsy, vsz]) # if zoom: # vss /= zoom # vfp = (vbb[0]+vbb[1])/2, (vbb[2]+vbb[3])/2, (vbb[4]+vbb[5])/2 # camera target # if viewup == 'z': # vup = (0,0,1) # camera up vector # vpos= vfp[0] + vss/1.9, vfp[1] + vss/1.9, vfp[2]+vss*0.01 # camera position # elif viewup == 'x': # vup = (1,0,0) # vpos= vfp[0]+vss*0.01, vfp[1] + vss/1.5, vfp[2] # camera position # else: # vup = (0,1,0) # vpos= vfp[0]+vss*0.01, vfp[1]+vss*0.01, vfp[2] + vss/1.5 # camera position # settings.notebook_plotter.camera = [vpos[0], vpos[1], vpos[2], # vfp[0], vfp[1], vfp[2], # vup[0], vup[1], vup[2] ] if not vp.axes: settings.notebook_plotter.grid_visible = False for ia in actors2show2: if isinstance(ia, (vtk.vtkCornerAnnotation, vtk.vtkAssembly)): continue kobj = None kcmap= None name = None if hasattr(ia, 'filename'): if ia.filename: name = os.path.basename(ia.filename) if ia.name: name = os.path.basename(ia.name) #####################################################################scalars # work out scalars first, Points Lines are also Mesh objs if isinstance(ia, (Mesh, shapes.Line, Points)): # print('scalars', ia.name, ia.N()) iap = ia.GetProperty() if isinstance(ia, (shapes.Line, Points)): iapoly = ia.polydata() else: iapoly = ia.clone().clean().triangulate().computeNormals().polydata() vtkscals = None color_attribute = None if ia.mapper().GetScalarVisibility(): vtkdata = iapoly.GetPointData() vtkscals = vtkdata.GetScalars() if vtkscals is None: vtkdata = iapoly.GetCellData() vtkscals = vtkdata.GetScalars() if vtkscals is not None: c2p = vtk.vtkCellDataToPointData() c2p.SetInputData(iapoly) c2p.Update() iapoly = c2p.GetOutput() vtkdata = iapoly.GetPointData() vtkscals = vtkdata.GetScalars() if vtkscals is not None: if not vtkscals.GetName(): vtkscals.SetName('scalars') scals_min, scals_max = ia.mapper().GetScalarRange() color_attribute = (vtkscals.GetName(), scals_min, scals_max) lut = ia.mapper().GetLookupTable() lut.Build() kcmap=[] nlut = lut.GetNumberOfTableValues() for i in range(nlut): r,g,b,a = lut.GetTableValue(i) kcmap += [i/(nlut-1), r,g,b] #####################################################################Volume if isinstance(ia, Volume): # print('Volume', ia.name, ia.dimensions()) kx, ky, kz = ia.dimensions() arr = ia.pointdata[0] kimage = arr.reshape(-1, ky, kx) colorTransferFunction = ia.GetProperty().GetRGBTransferFunction() kcmap=[] for i in range(128): r,g,b = colorTransferFunction.GetColor(i/127) kcmap += [i/127, r,g,b] kbounds = numpy.array(ia.imagedata().GetBounds()) \ + numpy.repeat(numpy.array(ia.imagedata().GetSpacing()) / 2.0, 2)\ * numpy.array([-1,1] * 3) kobj = k3d.volume(kimage.astype(numpy.float32), color_map=kcmap, #color_range=ia.imagedata().GetScalarRange(), alpha_coef=10, bounds=kbounds, name=name, ) settings.notebook_plotter += kobj #####################################################################text elif hasattr(ia, 'info') and 'formula' in ia.info.keys(): pos = (ia.GetPosition()[0],ia.GetPosition()[1]) kobj = k3d.text2d(ia.info['formula'], position=pos) settings.notebook_plotter += kobj #####################################################################Mesh elif isinstance(ia, Mesh) and ia.N() and len(ia.faces()): # print('Mesh', ia.name, ia.N(), len(ia.faces())) kobj = k3d.vtk_poly_data(iapoly, name=name, # color=_rgb2int(iap.GetColor()), color_attribute=color_attribute, color_map=kcmap, opacity=iap.GetOpacity(), wireframe=(iap.GetRepresentation()==1)) if iap.GetInterpolation() == 0: kobj.flat_shading = True settings.notebook_plotter += kobj #####################################################################Points elif isinstance(ia, Points): # print('Points', ia.name, ia.N()) kcols=[] if color_attribute is not None: scals = utils.vtk2numpy(vtkscals) kcols = k3d.helpers.map_colors(scals, kcmap, [scals_min,scals_max]).astype(numpy.uint32) # sqsize = numpy.sqrt(numpy.dot(sizes, sizes)) kobj = k3d.points(ia.points().astype(numpy.float32), color=_rgb2int(iap.GetColor()), colors=kcols, opacity=iap.GetOpacity(), shader=settings.k3dPointShader, point_size=iap.GetPointSize(), name=name, ) settings.notebook_plotter += kobj #####################################################################Lines elif ia.polydata(False).GetNumberOfLines(): # print('Line', ia.name, ia.N(), len(ia.faces()), # ia.polydata(False).GetNumberOfLines(), len(ia.lines()), # color_attribute, [vtkscals]) # kcols=[] # if color_attribute is not None: # scals = utils.vtk2numpy(vtkscals) # kcols = k3d.helpers.map_colors(scals, kcmap, # [scals_min,scals_max]).astype(numpy.uint32) # sqsize = numpy.sqrt(numpy.dot(sizes, sizes)) for i, ln_idx in enumerate(ia.lines()): if i>200: print('WARNING: K3D nr of line segments is limited to 200.') break pts = ia.points()[ln_idx] kobj = k3d.line(pts.astype(numpy.float32), color=_rgb2int(iap.GetColor()), opacity=iap.GetOpacity(), shader=settings.k3dLineShader, # width=iap.GetLineWidth()*sqsize/1000, name=name, ) settings.notebook_plotter += kobj #################################################################################### elif settings.notebookBackend == 'panel' and hasattr(vp, 'window') and vp.window: import panel # https://panel.pyviz.org/reference/panes/VTK.html vp.renderer.ResetCamera() settings.notebook_plotter = panel.pane.VTK(vp.window, width=int(vp.size[0]/1.5), height=int(vp.size[1]/2)) #################################################################################### elif 'ipyvtk' in settings.notebookBackend and hasattr(vp, 'window') and vp.window: from ipyvtklink.viewer import ViewInteractiveWidget vp.renderer.ResetCamera() settings.notebook_plotter = ViewInteractiveWidget(vp.window) #################################################################################### elif 'ipygany' in settings.notebookBackend: from ipygany import PolyMesh, Scene, IsoColor, RGB, Component from ipygany import Alpha, ColorBar, colormaps, PointCloud from ipywidgets import FloatRangeSlider, Dropdown, VBox, AppLayout, jslink bgcol = colors.rgb2hex(colors.getColor(vp.backgrcol)) actors2show2 = [] for ia in actors2show: if not ia: continue if isinstance(ia, vedo.Assembly): #unpack assemblies assacts = ia.unpack() for ja in assacts: if isinstance(ja, vedo.Assembly): actors2show2 += ja.unpack() else: actors2show2.append(ja) else: actors2show2.append(ia) pmeshes = [] colorbar = None for obj in actors2show2: # print("ipygany processing:", [obj], obj.name) if isinstance(obj, vedo.shapes.Line): lg = obj.diagonalSize()/1000 * obj.GetProperty().GetLineWidth() vmesh = vedo.shapes.Tube(obj.points(), r=lg, res=4).triangulate() vmesh.c(obj.c()) faces = vmesh.faces() # todo: Lines elif isinstance(obj, Mesh): vmesh = obj.triangulate() faces = vmesh.faces() elif isinstance(obj, Points): vmesh = obj faces = [] elif isinstance(obj, Volume): vmesh = obj.isosurface() faces = vmesh.faces() elif isinstance(obj, vedo.TetMesh): vmesh = obj.tomesh(fill=False) faces = vmesh.faces() else: print("ipygany backend: cannot process object type", [obj]) continue vertices = vmesh.points() scals = vmesh.inputdata().GetPointData().GetScalars() if scals and not colorbar: # there is an active array, only pick the first aname = scals.GetName() arr = vmesh.pointdata[aname] parr = Component(name=aname, array=arr) if len(faces): pmesh = PolyMesh(vertices=vertices, triangle_indices=faces, data={aname: [parr]}) else: pmesh = PointCloud(vertices=vertices, data={aname: [parr]}) rng = scals.GetRange() colored_pmesh = IsoColor(pmesh, input=aname, min=rng[0], max=rng[1]) if obj.scalarbar: colorbar = ColorBar(colored_pmesh) colormap_slider_range = FloatRangeSlider(value=rng, min=rng[0], max=rng[1], step=(rng[1] - rng[0]) / 100.) jslink((colored_pmesh, 'range'), (colormap_slider_range, 'value')) colormap = Dropdown( options=colormaps, description='Colormap:' ) jslink((colored_pmesh, 'colormap'), (colormap, 'index')) else: if len(faces): pmesh = PolyMesh(vertices=vertices, triangle_indices=faces) else: pmesh = PointCloud(vertices=vertices) if vmesh.alpha() < 1: colored_pmesh = Alpha(RGB(pmesh, input=tuple(vmesh.color())), input=vmesh.alpha()) else: colored_pmesh = RGB(pmesh, input=tuple(vmesh.color())) pmeshes.append(colored_pmesh) if colorbar: scene = AppLayout( left_sidebar=Scene(pmeshes, background_color=bgcol), right_sidebar=VBox((colormap_slider_range, #not working colorbar, colormap)), pane_widths=[2, 0, 1], ) else: scene = Scene(pmeshes, background_color=bgcol) settings.notebook_plotter = scene #################################################################################### elif '2d' in settings.notebookBackend.lower() and hasattr(vp, 'window') and vp.window: import PIL.Image try: import IPython except ImportError: raise Exception('IPython not available.') from vedo.io import screenshot settings.screeshotLargeImage = True nn = screenshot(returnNumpy=True, scale=settings.screeshotScale+2) pil_img = PIL.Image.fromarray(nn) settings.notebook_plotter = IPython.display.display(pil_img) return settings.notebook_plotter
# In[15]: #container for the main interface from ipywidgets import AppLayout, Layout title = 'Youtube Trend over Time' Title = widgets.HTML(value = f"<b><font size='5' color='Black'>{title}</b>") descrip="""How insane is it that sometimes you see the most amazing video on youtube, and yet it took nearly a decade for it to be popular? Or a subpar video which hits a million views within a week? A lot of it has to do with the way you market your content. Sponsoring advertisements for your posts helps, but it depends heavily on the textual supporting descriptions that you add. And an even deeper question is: what makes certain words more popular than others? What receives more hate by the public? Are certain topics more active during election years or during a pandemic? Fortunately, our platform and tools will figure it out for you . We’re trying to create a simple platform which serves as a proof of concept for how sentiment analysis can be extended to utility on a daily basis, with a very wide customer demographic. """ Descrip=widgets.HTML(value = f"<b><font size='2' color='Black'>{descrip}</b>") AppLayout(header=VBox([Title,Descrip]), left_sidebar=None, center=accordion, right_sidebar=None, footer=None) #widgets.IntSlider(description='c', #layout=Layout(height='auto', width='auto')))
def get_tab(self): # keys for the two models in self.models_compare dictionary m_ids = ['a', 'b'] def delta(cumul): diff = [] for i in range(1, len(cumul)): diff.append(cumul[i] - cumul[i - 1]) # first daily value is repeated since val(t0-1) is unknown diff.insert(0, diff[0]) return diff def delta_weekly(cumul): diff = [] for i in range(7, len(cumul), 7): diff.append((cumul[i] - cumul[i - 7]) / 7.) return diff def accum_weekly(daily): accum = [] for i in range(7, len(daily), 7): sum = 0 for j in range(i - 7, i): sum += daily[j] accum.append(sum / 7.) return accum def plot_total(self, model, sim_model, region, axis, y_axis_type='linear', y_max=0., scale=1.): start_day = (day0_widget.value - date(2020, 3, 1)).days region_data = None if region != 'None' and region != 'Simulation': region_data = self.data_description['regional_data'][region] for pop_name in model.populations: pop = model.populations[pop_name] if not pop.hidden: t = range(len(pop.history)) axis.plot(t, np.array(pop.history) * scale, lw=2, label=pop_name, color=pop.color) if region_data is not None: if pop_name in region_data: if 'total' in region_data[pop_name]: filename = region_data[pop_name]['total'][ 'filename'] header = region_data[pop_name]['total']['header'] data = self.pd_dict[filename][header].values td = range(len(data)) axis.scatter(td[start_day:], data[start_day:], color=pop.color, zorder=1) if region == 'Simulation': if self.sim_model is not None: sim_pop = self.sim_model.populations[pop_name] if hasattr(sim_pop, 'show_sim') and sim_pop.show_sim: st = range(len(sim_pop.history)) axis.scatter(st[start_day:], sim_pop.history[start_day:], color=sim_pop.color, zorder=1) title = 'Totals' if region_data is not None: title += ' - ' + region if region == 'Simulation': title += ' - Simulation' axis.set_title(title) axis.legend() axis.set_yscale(y_axis_type) day_offset = (day0_widget.value - model.t0).days axis.set_xlim(left=day_offset, right=n_days_widget.value) if y_axis_type == 'log': axis.set_ylim(bottom=3) else: axis.set_ylim(bottom=0) if (y_max > 0.): axis.set_ylim(top=y_max) def plot_daily(self, model, sim_model, region, axis, y_axis_type='linear', y_max=0., scale=1.): start_day = (day0_widget.value - date(2020, 3, 1)).days region_data = None if region != 'None' and region != 'Simulation': region_data = self.data_description['regional_data'][region] for pop_name in model.populations: pop = model.populations[pop_name] if not pop.hidden and pop.monotonic: daily = delta(pop.history) t = range(len(daily)) axis.step(t, np.array(daily) * scale, lw=2, label=pop_name, color=pop.color) if region_data is not None: if pop_name in region_data: if 'daily' in region_data[pop_name]: filename = region_data[pop_name]['daily'][ 'filename'] header = region_data[pop_name]['daily']['header'] data = self.pd_dict[filename][header].values td = range(len(data)) axis.scatter(td[start_day:], data[start_day:], color=pop.color, s=10, zorder=1) weekly_data = accum_weekly(data[start_day:]) tw = [ start_day + 3.5 + i * 7 for i in range(len(weekly_data)) ] axis.scatter(tw, weekly_data, color=pop.color, marker='*', s=100, zorder=1) else: filename = region_data[pop_name]['total'][ 'filename'] header = region_data[pop_name]['total']['header'] data = self.pd_dict[filename][header].values daily_data = delta(data) td = range(len(daily_data)) axis.scatter(td[start_day:], daily_data[start_day:], color=pop.color, s=10, zorder=1) weekly_data = delta_weekly(data[start_day:]) tw = [ start_day + 3.5 + i * 7 for i in range(len(weekly_data)) ] axis.scatter(tw, weekly_data, color=pop.color, marker='*', s=100, zorder=1) if region == 'Simulation': if self.sim_model is not None: sim_pop = self.sim_model.populations[pop_name] if hasattr(sim_pop, 'show_sim') and sim_pop.show_sim: sim_daily = delta(sim_pop.history) st = range(len(sim_daily)) axis.scatter(st[start_day:], sim_daily[start_day:], color=sim_pop.color, s=10, zorder=1) weekly_data = delta_weekly( sim_pop.history[start_day:]) tw = [ start_day + 3.5 + i * 7 for i in range(len(weekly_data)) ] axis.scatter(tw, weekly_data, color=pop.color, marker='*', s=100, zorder=1) title = 'Daily' if region_data is not None: title += ' - ' + region if region == 'Simulation': title += ' - Simulation' axis.set_title(title) axis.legend() axis.set_yscale(y_axis_type) day_offset = (day0_widget.value - model.t0).days axis.set_xlim(left=day_offset, right=n_days_widget.value) if y_axis_type == 'log': axis.set_ylim(bottom=3) else: axis.set_ylim(bottom=0) if (y_max > 0.): axis.set_ylim(top=y_max) day0_widget = widgets.DatePicker(description='day_0:', value=date(2020, 3, 1), tooltip='First day to show on plots') n_days = (date.today() - self.model_t0.value).days n_days = n_days - n_days % 10 + 10 n_days_widget = widgets.BoundedIntText( value=n_days, min=10, max=999, step=1, description='n_days:', tooltip='number of days to model: sets the upper time range of plots') plot_type = widgets.Dropdown( options=['linear total', 'log total', 'linear daily', 'log daily'], value='linear total', description='Plot Type:', tooltip='Type of plot to show') plot_scaled = widgets.Dropdown( options=['People', 'per 1000 people', 'per 1M people'], value='People', description='Plot scaling:', tooltip='Raw numbers or scaled?', disabled=False) plot_compare = widgets.Dropdown( options=['Side by side', 'Overlay'], value='Side by side', description='Compare:', tooltip='Select how you would like to make the comparison', disabled=True) y_max_compare = widgets.BoundedFloatText( value=0., min=0., max=1.E8, step=100., description='y_max:', tooltip='maximum of vertical axis for Plots (0 -> autoscale)') plot_output = widgets.Output() plot_button = widgets.Button(description=' Plot', button_style='', tooltip='Run model and plot result', icon='check') def make_plot(b): plot_output.clear_output(True) if len(self.models_compare) < 2: with plot_output: print( 'You must first load comparison models A and B. Go to the "Open" tab.' ) else: for i in range(2): m_id = m_ids[i] self.models_compare[m_id].reset() self.models_compare[m_id].evolve_expectations( n_days_widget.value) with plot_output: if plot_compare.value == 'Side by side': fig, axes = plt.subplots(1, 2, figsize=(16, 7)) y_axis_type = 'linear' if 'linear' not in plot_type.value: y_axis_type = 'log' y_max = y_max_compare.value for i in range(2): axis = axes[i] m_id = m_ids[i] model = self.models_compare[m_id] region_dropdown = self.region_dropdowns[i] region = region_dropdown.value scale = 1. scale_text = 'Number of People' if plot_scaled.value in [ 'per 1000 people', 'per 1M people' ]: if m_id in self.models_total_population: if self.models_total_population[ m_id] is not None: tot_pop = self.models_total_population[ m_id] if tot_pop > 0: if plot_scaled.value == 'per 1000 people': scale = 1000. / tot_pop else: scale = 1000000. / tot_pop scale_text = plot_scaled.value t0text = model.t0.strftime("%b %d") sim_model = None if region == 'Simulation': sim_model = copy.deepcopy(model) sim_model.reset() sim_model.generate_data(n_days_widget.value) if 'total' in plot_type.value: plot_total(self, model, sim_model, region, axis, y_axis_type, y_max, scale) else: plot_daily(self, model, sim_model, region, axis, y_axis_type, y_max, scale) plot_improvements(axis, t0text, scale_text) else: pass # to be implemented! plt.suptitle(comparison_notes.value, x=0.1, size='small', ha='left') self.last_plot = plt.gcf() plt.show() def plot_improvements(axis, t0text, scale_text): axis.set_xlabel('days since ' + t0text, horizontalalignment='right', position=(1., -0.1)) axis.set_ylabel(scale_text) pypm_props = dict(boxstyle='round', facecolor='blue', alpha=0.1) axis.text(0.01, 1.02, 'pyPM.ca', transform=axis.transAxes, fontsize=10, verticalalignment='bottom', bbox=pypm_props) plot_button.on_click(make_plot) # This will generally be called before data has been read, but will # be populated once the datafile is read region_list, region_selected = get_region_list(self) self.region_dropdowns = [ widgets.Dropdown(options=region_list, description='Region data:'), widgets.Dropdown(options=region_list, description='Region data:') ] plot_folder = widgets.Text(value='.', placeholder='relative to current folder', description='Folder:') plot_filename = widgets.Text(value='', tooltip='name', placeholder='filename', description='Filename:') def save_plot_file(b): pfn = plot_filename.value if len(pfn) > 0: # plot_filename = self.plot_folder_text_widget.value+'/'+pfn p_filename = pfn pfolder = plot_folder.value if pfolder not in ['', '.']: # plot_filename = self.plot_folder_text_widget.value+\ # '/'+pfolder+'/'+pfn p_filename = pfolder + '/' + pfn self.last_plot.savefig(p_filename) plot_filename.value = '' header_html = widgets.VBox([ widgets.HTML( value= "<h1><a href:='https://www.pypm.ca'>pyPM.ca</a></h1><p style='font-size: 26px;'>compare</p>", placeholder='', description='') ]) hspace = widgets.HTML(value=" " * 24, placeholder='Some HTML', description='') model_blocks = [ widgets.VBox([self.model_names[0], self.model_descriptions[0]]), widgets.VBox([self.model_names[1], self.model_descriptions[1]]) ] header_save_hspace = widgets.HTML(value=" " * 8, placeholder='Some HTML', description='') plot_save_button = widgets.Button( description=' Save plot', button_style='', tooltip='Save plot to the specified file', icon='image') plot_save_button.on_click(save_plot_file) plot_save = widgets.VBox([ widgets.HBox([plot_button, plot_save_button]), plot_folder, plot_filename ]) comparison_notes = widgets.Textarea( value='', tooltip='Notes on the comparison', placeholder='Notes on the comparison, to be printed on saved plot') header_hbox = widgets.HBox( [header_html, hspace, comparison_notes, header_save_hspace, plot_save]) left_box = widgets.VBox([model_blocks[0], self.region_dropdowns[0]]) center_box = widgets.VBox( [day0_widget, n_days_widget, plot_type, plot_scaled, y_max_compare]) right_box = widgets.VBox([model_blocks[1], self.region_dropdowns[1]]) return AppLayout(header=header_hbox, left_sidebar=left_box, center=center_box, right_sidebar=right_box, footer=plot_output, pane_widths=[2, 2, 2], pane_heights=[1, 2, '470px'])
def layout(header, left, right): layout = AppLayout(header=header, left_sidebar=left, center=None, right_sidebar=right) return layout
def visualize_it(res_file, temp_dir=".temp", default_index=0): import pathlib import meshio from ipygany import ColorBar, IsoColor, PolyMesh, Scene, Warp, colormaps from IPython.display import clear_output, display from ipywidgets import AppLayout, Dropdown, FloatSlider, VBox, jslink from ada.core.vector_utils import vector_length res_file = pathlib.Path(res_file).resolve().absolute() suffix = res_file.suffix.lower() suffix_map = {".rmed": "med", ".vtu": None} imesh = meshio.read(res_file, file_format=suffix_map[suffix]) imesh.point_data = { key.replace(" ", "_"): value for key, value in imesh.point_data.items() } def filter_keys(var): if suffix == ".vtu" and var != "U": return False if suffix == ".rmed" and var == "point_tags": return False return True warp_data = [key for key in filter(filter_keys, imesh.point_data.keys())] magn_data = [] for d in warp_data: res = [vector_length(v[:3]) for v in imesh.point_data[d]] res_norm = [r / max(res) for r in res] magn_data_name = f"{d}_magn" imesh.point_data[magn_data_name] = np.array(res_norm, dtype=np.float64) magn_data.append(magn_data_name) imesh.field_data = { key: np.array(value) for key, value in imesh.field_data.items() } tf = (pathlib.Path(temp_dir).resolve().absolute() / res_file.name).with_suffix(".vtu") if tf.exists(): os.remove(tf) os.makedirs(tf.parent, exist_ok=True) imesh.write(tf) mesh = PolyMesh.from_vtk(str(tf)) mesh.default_color = "gray" warp_vec = warp_data[default_index] try: colored_mesh = IsoColor(mesh, input=magn_data[default_index], min=0.0, max=1.0) except KeyError as e: trace_str = traceback.format_exc() logging.error(f'KeyError "{e}"\nTrace: "{trace_str}"') colored_mesh = mesh except ImportError as e: trace_str = traceback.format_exc() logging.error("This might be") logging.error(f'ImportError "{e}"\nTrace: "{trace_str}"') return warped_mesh = Warp(colored_mesh, input=warp_vec, warp_factor=0.0) warp_slider = FloatSlider(value=0.0, min=-1.0, max=1.0) jslink((warped_mesh, "factor"), (warp_slider, "value")) # Create a colorbar widget colorbar = ColorBar(colored_mesh) # Colormap choice widget colormap = Dropdown(options=colormaps, description="colormap:") jslink((colored_mesh, "colormap"), (colormap, "index")) # EigenValue choice widget eig_map = Dropdown(options=warp_data, description="Data Value:") scene = Scene([warped_mesh]) app = AppLayout(left_sidebar=scene, right_sidebar=VBox( (eig_map, warp_slider, colormap, colorbar)), pane_widths=[2, 0, 1]) def change_input(change): vec_name = change["new"] logging.info(vec_name) colored_mesh.input = vec_name + "_magn" warped_mesh.input = vec_name # Highly inefficient but likely needed due to bug https://github.com/QuantStack/ipygany/issues/69 clear_output() display(app) eig_map.observe(change_input, names=["value"]) return app
class CostWidget(object): def __init__(self, model): self._model = model @property def app(self): app_params = self._model._params.copy() cost = self._model.compute().values["Total Cost [$/tCO2]"] rsliders = {} esliders = {} all_sliders = {} labels = { "Scale [tCO2/year]": "Scale [tCO2/year]", "DAC Capacity Factor": "DAC Capacity Factor", "DAC Section Lead Time [years]": "DAC Section Lead Time [years]", "Total Capex [$]": "Overnight Capex [M$] *", "Electric Power Requierement [MW]": "Electric Power Requierement [MW] *", "Thermal [GJ/tCO2]": "Thermal [GJ/tCO2] *", "Fixed O+M Costs [$/tCO2]": "Fixed O+M Costs [$/tCO2]*", "Varible O+M Cost [$/tCO2]": "Varible O+M Cost [$/tCO2] *", "Economic Lifetime [years]": "Economic Lifetime [years]", "WACC [%]": "WACC [%]", "Natural Gas Cost [$/mmBTU]": "Natural Gas Cost [$/mmBTU]", } # --------- callbacks --------- # def update_cost(app_params): cost = self._model.compute().values["Total Cost [$/tCO2]"] result.value = f"<h1>${cost:0.2f}<h1/>" def on_value_change(param, change): app_params[param] = change["new"] update_cost(app_params) def set_defaults(change): case = change["new"] p = default_params(case.lower()) # TODO app_params.update(p) for k, v in app_params.items(): if k in all_sliders: all_sliders[k].value = v # --------- callbacks --------- # header = HTML(""" <h1> DAC Cost Estimator </h1> <b>By NOAH MCQUEEN and JOE HAMMAN</b> <div style="width:800px" <p> How much does it cost to build a Direct Air Capture facility? To help answer this question, we've built a calculator that takes the most important variables that drive the cost of building and operating a DAC plant. To find out more about the fundementals and assumptions in the calcuator, check out Noah's paper... </p> </div> """) # presets presets = Dropdown(description="Preset Scenario", options=["Low", "High"], value="Low") presets.observe(set_defaults, names="value") # report data result = HTML(value=f"<h1>${cost:0.2f}<h1/>") right = VBox( [HTML("<b>You can build this DAC plant for ... </b>"), result]) rsliders["Scale [tCO2/year]"] = FloatLogSlider( min=1, max=12, step=0.1, value=app_params["Scale [tCO2/year]"]) rsliders["DAC Capacity Factor"] = FloatSlider( min=0, max=1, step=0.01, readout_format=".2%", value=app_params["DAC Capacity Factor"]) rsliders["DAC Section Lead Time [years]"] = IntSlider( min=1, max=6, value=app_params["DAC Section Lead Time [years]"]) rsliders["Total Capex [$]"] = FloatSlider( value=app_params["Total Capex [$]"]) rsliders["Electric Power Requierement [MW]"] = FloatSlider( value=app_params["Electric Power Requierement [MW]"]) rsliders["Thermal [GJ/tCO2]"] = FloatSlider( value=app_params["Thermal [GJ/tCO2]"]) rsliders["Fixed O+M Costs [$/tCO2]"] = FloatSlider( value=app_params["Fixed O+M Costs [$/tCO2]"]) rsliders["Varible O+M Cost [$/tCO2]"] = FloatSlider( value=app_params["Varible O+M Cost [$/tCO2]"]) for key, slider in rsliders.items(): slider.observe(functools.partial(on_value_change, key), names="value") details = HTML(""" <h2>Report Data</h2> <p>Parameters from the <em>Report Data</em> worksheet...</p> """) report_data = VBox([details] + [ HBox([Label(labels[k], layout={"width": "250px"}), s]) for k, s in rsliders.items() ]) details = HTML(""" <h2>Economic Data</h2> <p>Parameters from the <em>Economic Parameters</em> worksheet...</p> """) # economic parameters esliders["Economic Lifetime [years]"] = IntSlider( min=1, max=50, value=app_params["Economic Lifetime [years]"]) esliders["WACC [%]"] = FloatSlider(min=0, max=1, step=0.01, readout_format=".2%", value=app_params["WACC [%]"]) esliders["Natural Gas Cost [$/mmBTU]"] = FloatSlider( min=0, max=10, step=0.1, value=app_params["Natural Gas Cost [$/mmBTU]"]) for key, slider in esliders.items(): slider.observe(functools.partial(on_value_change, key), names="value") econ_data = VBox([details] + [ HBox([Label(labels[k], layout={"width": "250px"}), s]) for k, s in esliders.items() ]) all_sliders = {**rsliders, **esliders} center = VBox([presets, report_data, econ_data]) return AppLayout(header=header, center=center, right_sidebar=right, width="900px")
def get_tab(self): output = widgets.Output() plot_output = widgets.Output() def plot_total(self, models, axis, y_axis_type='linear'): region = self.region_dropdown.value region_data = None if self.region_dropdown.value != 'None' and self.region_dropdown.value != 'Simulation': region_data = self.data_description['regional_data'][region] for pop_name in self.model.populations: pop = self.model.populations[pop_name] if (not pop.hidden) and pop.show_sim: t = range(len(pop.history)) axis.plot(t, pop.history, lw=2, label=pop_name, color=pop.color, zorder=2) x_ref = self.optimizer.data_range[1] y_ref = pop.history[x_ref] lower = [] upper = [] x_extend = range(x_ref, self.n_days_widget.value) for x in x_extend: dy_ref = pop.history[x] - y_ref values = [] for model in models: sim_pop = model.populations[pop_name] # scale the models to the same value at x_ref scale = pop.history[x_ref] / sim_pop.history[x_ref] values.append((sim_pop.history[x] - sim_pop.history[x_ref]) * scale - dy_ref) lower.append(np.percentile(values, 2.5)) upper.append(np.percentile(values, 97.5)) ref_hist = np.array( pop.history[x_ref:self.n_days_widget.value]) lower = np.array(lower) upper = np.array(upper) #symmetrize, since calculation with auto_covariance yields asymmetric solutions # - but for a monotonic function there should be asymmetry! #dy = np.maximum(np.abs(np.array(lower)), np.abs(np.array(upper))) #axis.fill_between(x_extend, ref_hist-dy, ref_hist+dy, color=pop.color, zorder=0, alpha=0.3) axis.fill_between(x_extend, ref_hist + lower, ref_hist + upper, color=pop.color, zorder=0, alpha=0.3) if region_data is not None: if pop_name in region_data: if 'total' in region_data[pop_name]: filename = region_data[pop_name]['total'][ 'filename'] header = region_data[pop_name]['total']['header'] data = self.pd_dict[filename][header].values td = range(len(data)) axis.scatter(td, data, color=pop.color, zorder=1) if region == 'Simulation': if self.sim_model is not None: sim_pop = self.sim_model.populations[pop_name] if hasattr(sim_pop, 'show_sim') and sim_pop.show_sim: st = range(len(sim_pop.history)) axis.scatter(st, sim_pop.history, color=sim_pop.color, zorder=1) title = 'Totals' if region_data is not None: title += ' - ' + region if region == 'Simulation': title += ' - Simulation (' + str(self.seed_text_widget.value) + ')' axis.set_title(title) axis.legend() axis.set_yscale(y_axis_type) axis.set_xlim(left=0, right=self.n_days_widget.value) if y_axis_type == 'log': axis.set_ylim(bottom=3) else: axis.set_ylim(bottom=0) def make_plot(models): output.clear_output(True) plot_output.clear_output(True) self.model.reset() self.model.evolve_expectations(self.n_days_widget.value) with plot_output: fig, axes = plt.subplots(1, 2, figsize=(16, 7)) axis = axes[0] y_axis_type = 'linear' plot_total(self, models, axis, y_axis_type) plot_improvements(axis) axis = axes[1] y_axis_type = 'log' plot_total(self, models, axis, y_axis_type) plot_improvements(axis) self.last_plot = plt.gcf() plt.show() def plot_improvements(axis): axis.set_xlabel('days since t0', horizontalalignment='right', position=(1., -0.1)) axis.set_ylabel('Number of people') pypm_props = dict(boxstyle='round', facecolor='blue', alpha=0.1) axis.text(0.01, 1.02, 'pyPM.ca', transform=axis.transAxes, fontsize=10, verticalalignment='bottom', bbox=pypm_props) variable_checkbox = widgets.Checkbox(value=False, description='variable', disabled=False) prior_par_text = widgets.Text(value='0,1', placeholder='prior parameters eg. 0.,1.', description='Prior pars:', disabled=True, continuous_update=False) prior_function_dropdown = widgets.Dropdown(options=['uniform', 'normal'], description='Prior:', disabled=True) mcmc_step_widget = widgets.FloatText(value=0., description='mcmc step:', continuous_update=False, disabled=True) def get_bounds(parameter, bound_text): # decode the bound_text bounds = [parameter.get_min(), parameter.get_max()] if bound_text.find(':') > 0: bound_split = bound_text.split(':') if len(bound_split) == 2: bounds[0] = float(bound_split[0]) bounds[1] = float(bound_split[1]) if parameter.parameter_type == 'int': bounds[0] = int(bounds[0]) bounds[1] = int(bounds[1]) return bounds def get_bounds_text(parameter): # turn the existing bounds into bound_text if parameter.parameter_type == 'float': bound_text = "{0:0.3f}:{1:0.3f}".format(parameter.get_min(), parameter.get_max()) elif parameter.parameter_type == 'int': bound_text = str(int(parameter.get_min())) + ':' + str( int(parameter.get_max())) return bound_text def get_par_vals(parameter, par_vals_text): # decode the par_vals par_vals = [(parameter.get_min() + parameter.get_max()) / 2, (parameter.get_max() - parameter.get_min()) / 2] if par_vals_text.find(',') > 0: par_vals_split = par_vals_text.split(',') if len(par_vals_split) == 2: par_vals[0] = float(par_vals_split[0]) par_vals[1] = float(par_vals_split[1]) if parameter.parameter_type == 'int': par_vals[0] = int(par_vals[0]) par_vals[1] = int(par_vals[1]) return par_vals def get_par_vals_text(parameter): # turn the existing par_vals into par_vals_text par_vals_text = '' if parameter.parameter_type == 'float': if parameter.prior_function is None or parameter.prior_function == 'uniform': if parameter.prior_parameters is None: mean = (parameter.get_min() + parameter.get_max()) / 2 half_width = (parameter.get_max() - parameter.get_min()) / 2 par_vals_text = "{0:0.3f},{1:0.3f}".format( mean, half_width) else: mean = parameter.prior_parameters['mean'] half_width = parameter.prior_parameters['half_width'] par_vals_text = "{0:0.3f},{1:0.3f}".format( mean, half_width) else: mean = parameter.prior_parameters['mean'] sigma = parameter.prior_parameters['sigma'] par_vals_text = "{0:0.3f},{1:0.3f}".format(mean, sigma) elif parameter.parameter_type == 'int': if parameter.prior_function is None: if parameter.prior_parameters is None: mean = (parameter.get_min() + parameter.get_max()) / 2 half_width = (parameter.get_max() - parameter.get_min()) / 2 par_vals_text = str(mean) + ',' + str(half_width) else: mean = parameter.prior_parameters['mean'] half_width = parameter.prior_parameters['half_width'] par_vals_text = str(mean) + ',' + str(half_width) return par_vals_text def variable_checkbox_eventhandler(change): # update the status of the model parameter - set bounds if appropriate output.clear_output(True) par_name = self.full_par_dropdown.value[2:] par = self.model.parameters[par_name] status_changed = False if variable_checkbox.value: if par.get_status() == 'fixed': status_changed = True par.set_variable(None, None) prior_par_text.disabled = False prior_par_text.value = get_par_vals_text(par) prior_function_dropdown.disabled = False if par.prior_function is None or par.prior_function == 'uniform': prior_function_dropdown.value = 'uniform' else: prior_function_dropdown.value = 'normal' mcmc_step_widget.disabled = False if par.mcmc_step is not None: mcmc_step_widget.value = par.mcmc_step else: prior_par_text.disabled = True prior_function_dropdown.disabled = True mcmc_step_widget.disabled = True if par.get_status() == 'variable': status_changed = True par.set_fixed() with output: print('Parameter ' + par_name + ' now set to fixed.') # update parameter list, if a variable changed its status # after updating, go back to select the revised par if status_changed: selected = self.full_par_dropdown.value prefix = selected[:2] full_par_names = get_par_list(self) self.full_par_dropdown.options = full_par_names if prefix == ' ': prefix = '* ' else: prefix = ' ' self.full_par_dropdown.value = prefix + selected[2:] variable_checkbox.observe(variable_checkbox_eventhandler, names='value') def prior_function_dropdown_eventhandler(change): par_name = self.full_par_dropdown.value[2:] par = self.model.parameters[par_name] prior_par_text.value = get_par_vals_text(par) prior_function_dropdown.observe(prior_function_dropdown_eventhandler, names='value') def prior_par_text_eventhandler(change): # update the prior values par_name = self.full_par_dropdown.value[2:] par = self.model.parameters[par_name] if variable_checkbox.value: par_vals = get_par_vals(par, prior_par_text.value) if prior_function_dropdown.value == 'uniform': prior_dict = {'mean': par_vals[0], 'half_width': par_vals[1]} par.set_variable('uniform', prior_dict) else: prior_dict = {'mean': par_vals[0], 'sigma': par_vals[1]} par.set_variable('norm', prior_dict) prior_par_text.observe(prior_par_text_eventhandler, names='value') def mcmc_step_change_eventhandler(change): par_name = self.full_par_dropdown.value[2:] par = self.model.parameters[par_name] par.mcmc_step = mcmc_step_widget.value mcmc_step_widget.observe(mcmc_step_change_eventhandler, names='value') def par_dropdown_eventhandler(change): # update list of visible parameters in case it has changed full_par_names = get_par_list(self) self.full_par_dropdown.options = full_par_names par_name = self.full_par_dropdown.value[2:] prefix = self.full_par_dropdown.value[:2] par = self.model.parameters[par_name] if prefix == '* ': variable_checkbox.value = True prior_par_text.disabled = False prior_par_text.value = get_par_vals_text(par) prior_function_dropdown.disabled = False if par.prior_function is not None and par.prior_function == 'norm': prior_function_dropdown.value = 'normal' else: prior_function_dropdown.value = 'uniform' mcmc_step_widget.disabled = False if hasattr(par, 'mcmc_step') and par.mcmc_step is not None: mcmc_step_widget.value = par.mcmc_step else: variable_checkbox.value = False prior_par_text.disabled = True prior_function_dropdown.disabled = True mcmc_step_widget.disabled = True self.full_par_dropdown.observe(par_dropdown_eventhandler, names='value') n_rep_widget = widgets.IntText(value=100, description='repetitions:', continuous_update=False, disabled=False) n_dof_widget = widgets.IntText(value=60, description='# dof:', continuous_update=False, disabled=False) chi2n_widget = widgets.FloatText(value=500., description='mean chi2n', continuous_update=False, disabled=False) n_mcmc_widget = widgets.IntText(value=5000, description='# MCMC:', continuous_update=False, disabled=False) chi2f_checkbox = widgets.Checkbox(value=False, description='calculate chi2f', disabled=False) auto_cov_button = widgets.Button( description='calc autocov', button_style='', tooltip='Calculate the autocovariance matrix', icon='') sim_gof_button = widgets.Button( description='calc sim gof', button_style='', tooltip= 'Calculate the goodness of fit statistic distribution for simulated samples', icon='') mcmc_button = widgets.Button(description=' Do MCMC', button_style='', tooltip='Produce an MCMC chain', icon='check') mcmc_plot_button = widgets.Button(description='mcmc plot', button_style='', tooltip='make a plot', icon='') def do_auto_cov(b): output.clear_output(True) n_rep = n_rep_widget.value n_points = self.optimizer.data_range[1] - self.optimizer.data_range[0] if n_rep < 2 * n_points: with output: print('Not enough repititions to calculate the') print('autocovariance. Should be more than double the') print('number of data points.') else: self.optimizer.calc_auto_covariance(n_rep) with output: print('Autocovariance calculated') auto_cov_button.on_click(do_auto_cov) def do_sim_gof(b): output.clear_output(True) n_rep = n_rep_widget.value self.optimizer.calc_chi2f = chi2f_checkbox.value self.optimizer.calc_chi2s = True self.optimizer.calc_sim_gof(n_rep) with output: print('Simulated goodness of fit distribution calculated') print('Take note of these values:') print('chi2d = {0:0.1f}'.format(self.optimizer.chi2d)) print('chi2m = {0:0.1f} sd = {1:0.1f}'.format( self.optimizer.chi2m, self.optimizer.chi2m_sd)) print('chi2n = {0:0.1f} sd = {1:0.1f}'.format( self.optimizer.chi2n, self.optimizer.chi2n_sd)) if chi2f_checkbox.value: print('chi2f = {0:0.1f} sd = {1:0.1f}'.format( self.optimizer.chi2f, self.optimizer.chi2f_sd)) print('chi2s = {0:0.1f} sd = {1:0.1f}'.format( self.optimizer.chi2s, self.optimizer.chi2s_sd)) sim_gof_button.on_click(do_sim_gof) def do_mcmc(b): output.clear_output(True) status = True # check that autocovariance matrix is calculated if self.optimizer.auto_cov is None: status = False with output: print('Auto covariance is needed before starting MCMC') # check that mcmc steps are defined. Check there are no integer variables for par_name in self.model.parameters: par = self.model.parameters[par_name] if par.get_status() == 'variable': if par.parameter_type != 'float': status = False with output: print( 'Only float parameters allowed in MCMC treatment') print('Remove: ' + par.name) elif par.mcmc_step is None: status = False with output: print('MCMC step size missing for: ' + par.name) if status: n_dof = n_dof_widget.value n_mcmc = n_mcmc_widget.value chi2n = chi2n_widget.value self.chain = self.optimizer.mcmc(n_dof, chi2n, n_mcmc) with output: print('MCMC chain produced.') print('fraction accepted =', self.optimizer.accept_fraction) mcmc_button.on_click(do_mcmc) def do_mcmc_plot(b): # draw 1/10 of the chain points at random # to produce an ensemble of data outcomes n_models = int(n_mcmc_widget.value / 10) n_days = self.n_days_widget.value models = [] for i in range(n_models): sim_model = copy.deepcopy(self.model) ipnt = int(n_models * stats.uniform.rvs()) link = self.chain[ipnt] for var_name in link: par = sim_model.parameters[var_name] par.set_value(link[var_name]) sim_model.reset() # produce data not expectations sim_model.generate_data(n_days) models.append(sim_model) make_plot(models) mcmc_plot_button.on_click(do_mcmc_plot) def fix_all(b): full_par_names = get_par_list(self) changed_list = [] for full_par_name in full_par_names: par_name = full_par_name[2:] prefix = full_par_name[:2] if prefix == '* ': par = self.model.parameters[par_name] par.set_fixed() changed_list.append(par_name) if len(changed_list) > 0: output.clear_output(True) # update the dropdown list full_par_names = get_par_list(self) self.full_par_dropdown.options = full_par_names with output: print('All variable parameters set to fixed:') print('\n'.join(changed_list)) fix_button = widgets.Button( description=' Fix all', button_style='', tooltip='Change all variable parameters to fixed', icon='warning') fix_button.on_click(fix_all) def show_vars(b): plot_output.clear_output(True) with plot_output: print(ptt.variable_parameter_table(self.model, width=110)) show_vars_button = widgets.Button( description=' Show variables', button_style='', tooltip='Show a table of variable parameters', icon='') show_vars_button.on_click(show_vars) hspace = widgets.HTML(value=" " * 24, placeholder='Some HTML', description='') header_html = widgets.VBox([ widgets.HTML( value= "<h1><a href:='https://www.pypm.ca'>pyPM.ca</a></h1><p style='font-size: 26px;'>MCMC</p>", placeholder='', description='') ]) buttons = widgets.VBox([ widgets.HBox([auto_cov_button, sim_gof_button]), widgets.HBox([mcmc_button, mcmc_plot_button]) ]) header_hbox = widgets.HBox( [header_html, hspace, show_vars_button, hspace, hspace, buttons]) left_box = widgets.VBox([ self.full_par_dropdown, variable_checkbox, prior_function_dropdown, prior_par_text, mcmc_step_widget, widgets.HBox([fix_button]) ]) right_box = widgets.VBox([ n_rep_widget, chi2n_widget, n_dof_widget, n_mcmc_widget, chi2f_checkbox ]) return AppLayout(header=header_hbox, left_sidebar=left_box, center=output, right_sidebar=right_box, footer=plot_output, pane_widths=[2, 2, 2], pane_heights=[1, 2, '460px'])
def get_tab(self): def delta(cumul): diff = [] for i in range(1, len(cumul)): diff.append(cumul[i] - cumul[i - 1]) # first daily value is repeated since val(t0-1) is unknown diff.insert(0, diff[0]) return diff def delta_weekly(cumul): diff = [] for i in range(7, len(cumul), 7): diff.append((cumul[i] - cumul[i - 7]) / 7.) return diff def accum_weekly(daily): accum = [] for i in range(7, len(daily), 7): sum = 0 for j in range(i - 7, i): sum += daily[j] accum.append(sum / 7.) return accum def plot_total(self, axis, y_axis_type='linear', y_max=0., y_min=0.): start_day = (t0_widget.value - date(2020, 3, 1)).days region = self.region_dropdown.value region_data = None if self.region_dropdown.value != 'None' and self.region_dropdown.value != 'Simulation': region_data = self.data_description['regional_data'][region] for pop_name in self.model.populations: pop = self.model.populations[pop_name] if not pop.hidden: t = range(len(pop.history)) axis.plot(t[start_day:], pop.history[start_day:], lw=2, label=pop_name, color=pop.color, zorder=2) if region_data is not None: if pop_name in region_data: if 'total' in region_data[pop_name]: filename = region_data[pop_name]['total'][ 'filename'] header = region_data[pop_name]['total']['header'] data = self.pd_dict[filename][header].values td = range(len(data)) axis.scatter(td[start_day:], data[start_day:], color=pop.color, zorder=1) if region == 'Simulation': if self.sim_model is not None: sim_pop = self.sim_model.populations[pop_name] if hasattr(sim_pop, 'show_sim') and sim_pop.show_sim: st = range(len(sim_pop.history)) axis.scatter(st[start_day:], sim_pop.history[start_day:], color=sim_pop.color, zorder=1) title = 'Totals' if region_data is not None: title += ' - ' + region if region == 'Simulation': title += ' - Simulation (' + str(self.get_seed_value()) + ')' axis.set_title(title) axis.legend() axis.set_yscale(y_axis_type) axis.set_xlim(left=start_day, right=self.n_days_widget.value) if y_axis_type == 'log': axis.set_ylim(bottom=max(3, y_min)) else: axis.set_ylim(bottom=y_min) if (y_max > 0.): axis.set_ylim(top=y_max) def plot_residual(self, axis, y_max=0.): start_day = (t0_widget.value - date(2020, 3, 1)).days region = self.region_dropdown.value region_data = None if self.region_dropdown.value != 'None' and self.region_dropdown.value != 'Simulation': region_data = self.data_description['regional_data'][region] for pop_name in self.model.populations: pop = self.model.populations[pop_name] if not pop.hidden: #t = range(len(pop.history)) #axis.plot(t, pop.history, lw=2, label=pop_name, color=pop.color, zorder=2) if region_data is not None: if pop_name in region_data: if 'total' in region_data[pop_name]: filename = region_data[pop_name]['total'][ 'filename'] header = region_data[pop_name]['total']['header'] data = self.pd_dict[filename][header].values td = range(len(data)) residual = [data[i] - pop.history[i] for i in td] axis.scatter(td[start_day:], residual[start_day:], label=pop_name, color=pop.color, zorder=1) if region == 'Simulation': if self.sim_model is not None: sim_pop = self.sim_model.populations[pop_name] if hasattr(sim_pop, 'show_sim') and sim_pop.show_sim: st = range(len(sim_pop.history)) residual = [ sim_pop.history[i] - pop.history[i] for i in st ] axis.scatter(st[start_day:], residual[start_day:], label=pop_name, color=sim_pop.color, zorder=1) title = 'Residuals: Totals' if region_data is not None: title += ' - ' + region if region == 'Simulation': title += ' - Simulation (' + str(self.get_seed_value()) + ')' axis.set_title(title) axis.legend() axis.set_xlim(left=0, right=self.n_days_widget.value) if (y_max > 0.): axis.set_ylim(top=y_max) axis.set_ylim(bottom=-y_max) def plot_daily(self, axis, y_axis_type='linear', y_max=0., y_min=0.): start_day = (t0_widget.value - date(2020, 3, 1)).days region = self.region_dropdown.value region_data = None if self.region_dropdown.value != 'None' and self.region_dropdown.value != 'Simulation': region_data = self.data_description['regional_data'][region] for pop_name in self.model.populations: pop = self.model.populations[pop_name] if not pop.hidden and pop.monotonic: daily = delta(pop.history) t = range(len(daily)) axis.step(t[start_day:], daily[start_day:], lw=2, label=pop_name, color=pop.color, zorder=2) if region_data is not None: if pop_name in region_data: if 'daily' in region_data[pop_name]: filename = region_data[pop_name]['daily'][ 'filename'] header = region_data[pop_name]['daily']['header'] data = self.pd_dict[filename][header].values td = range(len(data)) axis.scatter(td[start_day:], data[start_day:], color=pop.color, s=10, zorder=1) weekly_data = accum_weekly(data[start_day:]) tw = [ start_day + 3.5 + i * 7 for i in range(len(weekly_data)) ] axis.scatter(tw, weekly_data, color=pop.color, marker='*', s=100, zorder=1) else: filename = region_data[pop_name]['total'][ 'filename'] header = region_data[pop_name]['total']['header'] data = self.pd_dict[filename][header].values daily_data = delta(data) td = range(len(daily_data)) axis.scatter(td[start_day:], daily_data[start_day:], color=pop.color, s=10, zorder=1) weekly_data = delta_weekly(data[start_day:]) tw = [ start_day + 3.5 + i * 7 for i in range(len(weekly_data)) ] axis.scatter(tw, weekly_data, color=pop.color, marker='*', s=100, zorder=1) if region == 'Simulation': if self.sim_model is not None: sim_pop = self.sim_model.populations[pop_name] if hasattr(sim_pop, 'show_sim') and sim_pop.show_sim: sim_daily = delta(sim_pop.history) st = range(len(sim_daily)) axis.scatter(st[start_day:], sim_daily[start_day:], color=sim_pop.color, s=10, zorder=1) weekly_data = delta_weekly( sim_pop.history[start_day:]) tw = [ start_day + 3.5 + i * 7 for i in range(len(weekly_data)) ] axis.scatter(tw, weekly_data, color=pop.color, marker='*', s=100, zorder=1) title = 'Daily' if region_data is not None: title += ' - ' + region if region == 'Simulation': title += ' - Simulation (' + str(self.get_seed_value()) + ')' axis.set_title(title) axis.legend() axis.set_yscale(y_axis_type) axis.set_xlim(left=start_day, right=self.n_days_widget.value) if y_axis_type == 'log': axis.set_ylim(bottom=max(y_min, 3)) else: axis.set_ylim(bottom=y_min) if (y_max > 0.): axis.set_ylim(top=y_max) # the t0 information needs to be propagated correctly before enabling this widget: t0_widget = widgets.DatePicker(description='t_0:', value=date(2020, 3, 1), tooltip='Defines day 0 on plots', disabled=False) # Look into this later: # time_step_widget = widgets.BoundedFloatText( # value=1., min=0.02, max=2.0, step=0.05, description='time_step:', # tooltip='length of each step in the calculation: disabled for now', disabled=True) plot_1 = widgets.Dropdown( options=[ 'linear total', 'log total', 'residual total', 'linear daily', 'log daily' ], value='linear total', description='Plot #1:', tooltip='Plot on left if the second plot is not None') plot_2 = widgets.Dropdown(options=[ 'linear total', 'log total', 'residual total', 'linear daily', 'log daily' ], value='log total', description='Plot #2:', tooltip='Plot on the right') y_max_1 = widgets.BoundedFloatText( value=0., min=0., max=1.E8, step=100., description='y_max #1:', tooltip='maximum of vertical axis for Plot #1. (0 -> autoscale)', disabled=False) y_min_1 = widgets.BoundedFloatText( value=0., min=0., max=1.E8, step=100., description='y_min #1:', tooltip='minimum of vertical axis for Plot #1. (0 -> autoscale)', disabled=False) y_max_2 = widgets.BoundedFloatText( value=0., min=0., max=1.E8, step=100., description='y_max #2:', tooltip='maximum of vertical axis for Plot #2. (0 -> autoscale)', disabled=False) y_min_2 = widgets.BoundedFloatText( value=0., min=0., max=1.E8, step=100., description='y_min #2:', tooltip='minimum of vertical axis for Plot #2. (0 -> autoscale)', disabled=False) output = widgets.Output() plot_output = widgets.Output() #plot_output.layout.height = '50px' plot_button = widgets.Button(description=' Plot', button_style='', tooltip='Run model and plot result', icon='check') reset_button = widgets.Button( description=' Reset', button_style='warning', tooltip='Undo all changes to parameters since loading model', icon='warning') def make_plot(b): output.clear_output(True) plot_output.clear_output(True) if self.region_dropdown.value == 'Simulation': self.sim_model = copy.deepcopy(self.model) # produce a new seed if the text_widget value is zero seed = self.get_seed_value(new_seed=True) np.random.seed(seed) self.sim_model.reset() self.sim_model.generate_data(self.n_days_widget.value, data_start=data_start_widget.value) # since there could be new simulation data: self.new_region_opened() #self.model.parameters[self.param_dropdown.value].set_value(self.val_text_widget.value) #run model with current parameters before = time.process_time() self.model.reset() self.model.evolve_expectations(self.n_days_widget.value) after = time.process_time() run_time = int(round((after - before) * 1000.)) with output: dash = '-' * 33 print('Run time = ' + str(run_time) + ' ms') print() print('Max. expectations in the period:') print() print('population max day') print(dash) for pop_name in self.model.populations: pop = self.model.populations[pop_name] if not pop.hidden: print('{:<22s}{:>5d}{:>5d}'\ .format(pop_name,int(round(np.max(pop.history))), int(round(np.argmax(pop.history))))) with plot_output: fig, axes = plt.subplots(1, 2, figsize=(16, 7)) axis = axes[0] y_axis_type = 'linear' if 'linear' not in plot_1.value: y_axis_type = 'log' y_max = y_max_1.value y_min = y_min_1.value if 'total' in plot_1.value: if 'residual' in plot_1.value: plot_residual(self, axis, y_max) else: plot_total(self, axis, y_axis_type, y_max, y_min) else: plot_daily(self, axis, y_axis_type, y_max, y_min) plot_improvements(axis) axis = axes[1] y_axis_type = 'linear' if 'linear' not in plot_2.value: y_axis_type = 'log' y_max = y_max_2.value y_min = y_min_2.value if 'total' in plot_2.value: if 'residual' in plot_2.value: plot_residual(self, axis, y_max) else: plot_total(self, axis, y_axis_type, y_max, y_min) else: plot_daily(self, axis, y_axis_type, y_max, y_min) plot_improvements(axis) self.last_plot = plt.gcf() plt.show() def plot_improvements(axis): t0text = date(2020, 3, 1).strftime("%b %d") axis.set_xlabel('days since ' + t0text, horizontalalignment='right', position=(1., -0.1)) axis.set_ylabel('Number of people') pypm_props = dict(boxstyle='round', facecolor='blue', alpha=0.1) axis.text(0.01, 1.02, 'pyPM.ca', transform=axis.transAxes, fontsize=10, verticalalignment='bottom', bbox=pypm_props) start_day = (t0_widget.value - date(2020, 3, 1)).days # indicate times of transitions x_transform = transforms.blended_transform_factory( axis.transData, axis.transAxes) trans_list, trans_enabled = get_transitions_lists(self) i = 0 n_mod = 0 # multiple bands if multiple parameters to be changed prefix = 8 tran_dict = {} for tran_name in trans_enabled: tran = self.model.transitions[tran_name] if hasattr(tran, 'parameter_after'): if tran_name[0:prefix] not in tran_dict: tran_dict[tran_name[0:prefix]] = { 'y_min': 0., 'y_max': 1., 'n_mod': 0, 'last_mod': 0 } n_bands = len(tran_dict) if n_bands > 1.: d_band = 1. / n_bands low = 0. for key in tran_dict: tran_dict[key]['y_min'] = low tran_dict[key]['y_max'] = low + d_band low += d_band for tran_name in trans_enabled: tran = self.model.transitions[tran_name] if hasattr(tran, 'parameter_after'): # a modifier changes a parameter - use a color band to distinguish regions tran_dict[tran_name[0:prefix]]['n_mod'] += 1 n_mod = tran_dict[tran_name[0:prefix]]['n_mod'] last_mod = tran_dict[tran_name[0:prefix]]['last_mod'] y_min = tran_dict[tran_name[0:prefix]]['y_min'] y_max = tran_dict[tran_name[0:prefix]]['y_max'] axis.axvspan(last_mod, tran.trigger_step, facecolor='papayawhip', edgecolor='tan', alpha=0.5, zorder=-n_mod, ymin=y_min, ymax=y_max) tran_dict[tran_name[0:prefix]]['last_mod'] = tran.trigger_step else: # an injector adds population - use an circle to show times (delayed by a week?) i += 1 x_text = 'X' + str(i) x_props = dict(boxstyle='circle', facecolor='red', alpha=0.3) # a hack to put it in the right place (since a 1 week delay - need to get 7 from somewhere) delay = 7. / self.model.get_time_step() if tran.trigger_step + delay > start_day and tran.trigger_step + delay < self.n_days_widget.value: axis.text(tran.trigger_step + delay, -0.1, x_text, transform=x_transform, fontsize=10, verticalalignment='top', horizontalalignment='center', bbox=x_props) def reset_parameters(b): output.clear_output(True) self.model.reset() for par_name in self.model.parameters: par = self.model.parameters[par_name] par.reset() par_down = self.param_dropdown if par_down.value in self.model.parameters: reset_value = self.model.parameters[par_down.value].get_value() self.val_text_widget.value = reset_value with output: print('All parameters reset') print('to their initial values!') plot_button.on_click(make_plot) reset_button.on_click(reset_parameters) pars = get_par_list(self) self.param_dropdown = widgets.Dropdown(options=pars, description='Parameter:', disabled=False) par = self.model.parameters[pars[0]] #Bug in BoundedFloatText - regularly incorrect read back #val_text = widgets.BoundedFloatText(min=par.get_min(), max=par.get_max(), value = par.get_value()) #similar bug in the slide #val_slide = widgets.FloatSlider(min=par.get_min(), max=par.get_max(), value = par.get_value(), # continuous_update=False, orientation='horizontal', readout=True, readout_format='.3f') self.val_text_widget = widgets.FloatText(value=par.get_value(), description='Value:', continuous_update=False) #widgets.link((val_slide, 'value'), (val_text, 'value')) def dropdown_eventhandler(change): # update list of visible parameters in case it has changed pars = get_par_list(self) self.param_dropdown.options = pars par = self.model.parameters[self.param_dropdown.value] self.val_text_widget.value = par.get_value() def val_change_eventhandler(change): if self.param_dropdown.value in self.model.parameters: par = self.model.parameters[self.param_dropdown.value] if par.parameter_type == 'float': par.set_value(change['new']) else: par.set_value(int(change['new'])) b = [] make_plot(b) self.param_dropdown.observe(dropdown_eventhandler, names='value') self.val_text_widget.observe(val_change_eventhandler, names='value') trans_list, trans_enabled = get_transitions_lists(self) self.transitions_chooser = widgets.SelectMultiple( options=trans_list, value=trans_enabled, rows=1, description='Transitions:') def tran_choo_eventhandler(change): output.clear_output(True) trans_enabled = self.transitions_chooser.value with output: print('Changes made to transition status:') for tran_name in self.model.transitions: tran = self.model.transitions[tran_name] prev_enabled = tran.enabled was_enabled = ' was disabled' if tran.enabled: was_enabled = ' was enabled' # set the bit in the model: tran.enabled = tran_name in trans_enabled now_enabled = 'and is now disabled.' if tran.enabled: now_enabled = 'and is now enabled.' if prev_enabled != tran.enabled: print(tran_name + was_enabled) print(now_enabled) self.transitions_chooser.observe(tran_choo_eventhandler, names='value') def region_dropdown_eventhandler(change): output.clear_output(True) region_selected = self.region_dropdown.value if self.data_description is not None: self.data_description['selected_region'] = region_selected if region_selected == 'Simulation': self.seed_text_widget.disabled = False data_start_widget.disabled = False else: self.seed_text_widget.disabled = True data_start_widget.disabled = True with output: print('Changed data region to: ' + region_selected) self.new_region_opened() self.region_dropdown.observe(region_dropdown_eventhandler, names='value') self.seed_text_widget = widgets.IntText( value=0, description='Seed:', disabled=True, tooltip='To use a fixed seed for simulation, enter an integer', continuous_update=False) data_start_widget = widgets.IntText( value=0, description='Data start:', disabled=True, tooltip='Enter step for simulation to start', continuous_update=False) def save_model_file(b): output.clear_output(True) mfn = model_filename.value if len(mfn) > 0: if '.pypm' not in mfn: mfn = mfn + '.pypm' #filename = self.model_folder_text_widget.value+'/'+mfn filename = mfn mfolder = model_folder.value if mfolder not in ['', '.']: # filename = self.model_folder_text_widget.value+\ # '/'+mfolder+'/'+mfn filename = mfolder + '/' + mfn self.model.name = self.model_name.value self.model.description = self.model_description.value self.model.save_file(filename) with output: print('Success. Model saved to:') print(filename) model_filename.value = '' else: with output: print(' Model not saved: Missing filename.') def save_plot_file(b): # use the same widgets for filename as model output.clear_output(True) with output: mfn = model_filename.value if len(mfn) > 0: #plot_filename = self.model_folder_text_widget.value+'/'+mfn plot_filename = mfn mfolder = model_folder.value if mfolder not in ['', '.']: #plot_filename = self.model_folder_text_widget.value+\ # '/'+mfolder+'/'+mfn plot_filename = mfolder + '/' + mfn self.last_plot.savefig(plot_filename) print('The plot was saved to:') print(plot_filename) model_filename.value = '' else: print('No filename provided.') print('Please try again.') hspace = widgets.HTML(value=" " * 12, placeholder='Some HTML', description='') model_id = widgets.VBox([self.model_name, self.model_description]) header_save_hspace = widgets.HTML(value=" " * 16, placeholder='Some HTML', description='') model_folder = widgets.Text(value='.', placeholder='relative to current model folder', description='Folder:') model_filename = widgets.Text(value='', tooltip='name', placeholder='filename', description='Filename:') model_save_button = widgets.Button( description=' Save model', button_style='', tooltip='Save model as currently defined to the specified file', icon='file') plot_save_button = widgets.Button( description=' Save plot', button_style='', tooltip='Save plot to the specified file', icon='image') model_save = widgets.VBox([ widgets.HBox([model_save_button, plot_save_button]), model_folder, model_filename ]) #model_upload = widgets.FileUpload(accept='.pypm',multiple=False) #def model_upload_eventhandler(change): # filename = list(model_upload.value.keys())[0] # my_pickle = model_upload.value[filename]['content'] # self.open_model(filename, my_pickle) #model_upload.observe(model_upload_eventhandler, names='value') header_html = widgets.VBox([ widgets.HTML( value= "<h1><a href:='https://www.pypm.ca'>pyPM.ca</a></h1><p style='font-size: 26px;'>explore</p>", placeholder='', description='') ]) header_hbox = widgets.HBox( [header_html, hspace, model_id, header_save_hspace, model_save]) model_save_button.on_click(save_model_file) plot_save_button.on_click(save_plot_file) left_box = widgets.VBox([ t0_widget, self.n_days_widget, plot_1, plot_2, y_max_1, y_min_1, y_max_2, y_min_2 ]) right_box = widgets.VBox([ widgets.HBox([plot_button, reset_button]), self.param_dropdown, self.val_text_widget, self.transitions_chooser, self.region_dropdown, self.seed_text_widget, data_start_widget ]) return AppLayout(header=header_hbox, left_sidebar=left_box, center=output, right_sidebar=right_box, footer=plot_output, pane_widths=[2, 2, 2], pane_heights=[1, 2, '460px'])
x = lin['campaign_id'] y = lin['campaign_count'] lines = plt.plot(x,y) def update_lines(change): plt.title('Plotting of linear graph'.format(change.new)) lines[0].set_data(x, y) fig.canvas.draw() fig.canvas.flush_events() slider.observe(update_lines, names='value') AppLayout( center=fig.canvas, footer=slider, pane_heights=[0, 6, 1] ) # In[ ]: # In[31]: #df6.head(5) #df6 = df6.groupby[df['jid'],df['campaign']]
def draw_roaming_ui(): global iter_slider, reset_button, color_it_button, juliabrot_button, canvases global drawing, uly_select, ulx_select, color_list, picker1, picker2, bump_ud_slider, hue_slider, sat_slider, val_slider global lry_select, lrx_select, color_it, modulo_slider, picker3, bump_lr_slider, zoom_slider, save_button # This establishes the size of the preview gui drawing = False color_it = True uly_select = 0 ulx_select = 0 lry_select = jgrid.settings.sizeY lrx_select = jgrid.settings.sizeX canvases = MultiCanvas(3, width=jgrid.settings.sizeX * 2.5, height=jgrid.settings.sizeY + 75) canvases[drawing_layer].font = '25px serif' canvases[drawing_layer].fill_style = '#aaaaaa' canvases[drawing_layer].line_width = 3 canvases[interaction_layer].font = '35px serif' canvases[interaction_layer].fill_style = '#eee800' canvases[interaction_layer].stroke_style = '#ffffff' canvases[interaction_layer].line_width = 3 iter_slider = FloatLogSlider(description='Iterations:', base=10, value=jgrid.settings.max_iterations, min=1, max=7, step=.01, continuous_update=False) iter_slider.observe(handler=iter_slider_handler, names='value') max_lr_bump = jgrid.settings.sizeX max_ud_bump = jgrid.settings.sizeY bump_ud_slider = IntSlider(description='Bump UD pix:', value=1, min=0, max=max_ud_bump, step=1, continuous_update=False) bump_lr_slider = IntSlider(description='Bump LR pix:', value=1, min=0, max=max_lr_bump, step=1, continuous_update=False) zoom_slider = FloatSlider(description='Zoom:', value=2.0, min=0.0, max=1000.0, step=.001, continuous_update=False) #zoom_slider.observe(handler=zoom_button_handler, names='value') hue_slider = FloatSlider(description='Hue :', value=jgrid.settings.hue, min=0.0, max=1.0, step=.001, continuous_update=False) sat_slider = FloatSlider(description='Sat:', value=jgrid.settings.sat, min=0.0, max=1.0, step=.01, continuous_update=False) val_slider = FloatSlider(description='Val:', value=jgrid.settings.val, min=0.0, max=1.0, step=.02, continuous_update=False) hue_slider.observe(handler=hue_slider_handler, names='value') sat_slider.observe(handler=sat_slider_handler, names='value') val_slider.observe(handler=val_slider_handler, names='value') modulo_slider = IntSlider(description='Modulo:', value=jgrid.settings.modulo, min=1, max=1000000, step=1, continuous_update=False) modulo_slider.observe(handler=modulo_slider_handler, names='value') canvases[interaction_layer].on_mouse_down(on_mouse_down) canvases[interaction_layer].on_mouse_move(on_mouse_move) reset_button = Button(description='Zoom', disabled=False, button_style='', tooltip='Click to use zoom slider setting for zoom', icon='') reset_button.on_click(zoom_button_handler) save_button = Button(description='Save', disabled=False, button_style='', tooltip='Click to save as JSON settings file', icon='') save_button.on_click(save_button_handler) color_it_button = Button(description='Color/BW', disabled=False, button_style='', tooltip='Click for BW or Color', icon='') color_it_button.on_click(color_button_handler) juliabrot_button = Button(description='JM Mode', disabled=False, button_style='', tooltip='Click for Julia or Mandelbrot', icon='') juliabrot_button.on_click(juliabrot_button_handler) undo_button = Button(description='Undo', disabled=False, button_style='', tooltip='Click to revert to last view', icon='') undo_button.on_click(undo_button_handler) bleft_button = Button(description='Bump L', disabled=False, button_style='', tooltip='Click to nudge left num bump LR pixels', icon='') bleft_button.on_click(bleft_button_handler) bright_button = Button(description='Bump R', disabled=False, button_style='', tooltip='Click to nudge right num bump LR pixels', icon='') bright_button.on_click(bright_button_handler) bup_button = Button(description='Bump U', disabled=False, button_style='', tooltip='Click to nudge up num bump UD pixels', icon='') bup_button.on_click(bup_button_handler) bdown_button = Button(description='Bump D', disabled=False, button_style='', tooltip='Click to nudge down bump UD pixels', icon='') bdown_button.on_click(bdown_button_handler) picker1 = ColorPicker(description='M Color:', value=jgrid.settings.m_color) #picker2 = ColorPicker(description='Color 1:', value='#fff800') #picker3 = ColorPicker(description='Color 2:', value='#fff800') picker1.observe(color_picker1_handler, names='value') #picker2.observe(color_picker2_handler, names='value') #picker3.observe(color_picker3_handler, names='value') color_list = Dropdown(disabled=False, options=[('Rainbow', 1), ('Classic', 2), ('Log', 3), ('RGB Max Iter', 4), ('Rainbow 2', 5)], value=jgrid.settings.color_mode, description='Color Mode:', tooltip='Select built-in coloring options') color_list.observe(color_select_handler, names='value') draw_fractal(canvases, jgrid.tile_list) display_info(canvases, jgrid) return AppLayout(center=canvases, header=HBox((iter_slider, bump_ud_slider, bump_lr_slider, zoom_slider)), right_sidebar=VBox( (picker1, color_list, hue_slider, sat_slider, val_slider, modulo_slider)), footer=HBox( (bleft_button, bright_button, bup_button, bdown_button, color_it_button, juliabrot_button, reset_button, undo_button, save_button)))
m.layout.height = 'auto' fig.layout.width = 'auto' fig.layout.height = 'auto' # In[30]: out = HTML(value='', layout=Layout(width='auto', height='auto')) # In[31]: AppLayout(center=m, header=header, left_sidebar=VBox([ Label("Basemap:"), basemap_selector, Label("Overlay:"), heatmap_selector ]), right_sidebar=fig, footer=out, pane_widths=['80px', 1, 1], pane_heights=['80px', 4, 1], height='600px', grid_gap="30px") # In[11]: row = [] # In[12]: X, Y = np.mgrid[-90:90:10j, -180:180:20j] # In[13]: