def plot(self): """ Plots the vp and vs model as html files. Looks nice, but is pretty costly, so expect some waiting time for bigger models. Note that vp and vs are flattened values. Returns ------- figvp : plotly.graphs_objs._figure.Figure Figure containg vp model. figvs : plotly.graphs_objs._figure.Figure Figure containing vs model. """ x, y, z = np.meshgrid(self.lat, self.lon, self.z) figvp = go.Figure(data=go.Volume( x=x.flatten(), y=y.flatten(), z=z.flatten(), value=self.vpf.flatten(), isomin=0, isomax=10, opacity=0.3, # needs to be small to see through all surfaces surface_count=21, # surface_count # needs to be a large number for good volume rendering )) figvs = go.Figure(data=go.Volume( x=x.flatten(), y=y.flatten(), z=z.flatten(), value=self.vsf.flatten(), isomin=0, isomax=10, opacity=0.3, # needs to be small to see through all surfaces surface_count=21, # needs to be a large number for good volume rendering )) # plot(figvp) # plot(figvs) return figvp, figvs
def update_plot(data): res = cp.parse_dict(data) _ = [item.to("ppm", "nmr_frequency_ratio") for item in res.x] x, y, z = [item.coordinates.value for item in res.x] x_, y_, z_ = np.meshgrid(x, y, z, indexing="ij") trace = go.Volume( x=x_.ravel(), y=y_.ravel(), z=z_.ravel(), value=res.y[0].components[0].T.ravel(), isomin=0.05, isomax=0.95, opacity=0.1, # needs to be small to see through all surfaces surface_count=25, # needs to be a large number for good volume rendering colorscale="RdBu", ) return {"data": [trace]}
def plot_volume(array: np.ndarray): _, x, y, z = array.shape X, Y, Z = np.mgrid[:x, :y, :z] fig = go.Figure(data=go.Volume(x=X.flatten(), y=Y.flatten(), z=Z.flatten(), value=array.flatten(), isomin=0, isomax=1, opacity=0.5, opacityscale="max", surface_count=5)) f = StringIO() fig.write_html(f, full_html=False) f.seek(0) return f.read()
def _draw_slice(figure, axis, volume, opacity=0.3, step=None, n_steps=0): if step is None: height = volume.shape[axis] // 2 visible = True else: height = (volume.shape[axis] * step) // n_steps visible = False v_min = volume.min() sf = volume.max() - v_min if axis == Axes.X: X, Y, Z = np.mgrid[height:height + 1, :volume.shape[1], :volume.shape[2]] values = volume[height, :, :].flatten() elif axis == Axes.Y: X, Y, Z = np.mgrid[:volume.shape[0], height:height + 1, :volume.shape[2]] values = volume[:, height, :].flatten() elif axis == Axes.Z: X, Y, Z = np.mgrid[:volume.shape[0], :volume.shape[1], height:height + 1] values = volume[:, :, height].flatten() values = 1 - (values - v_min) / sf figure.add_trace( go.Volume( x=X.flatten(), y=Y.flatten(), z=Z.flatten(), value=values, colorscale='greys', surface_count=1, showscale=False, opacity=opacity, visible=visible, name=_name_from_enum(axis), hoverinfo='skip' ) )
def drawPlotly(self, schematic, title="", ptype="scatter"): x = [] y = [] z = [] id = [] clrs = [] if type(schematic) is torch.Tensor: sizes = list(schematic.size()) for i in range(sizes[0]): for j in range(sizes[1]): for k in range(sizes[2]): if schematic[i, j, k] > 0: x.append(i) y.append(j) z.append(k) id.append(schematic[i, j, k].item()) elif type(schematic) is np.ndarray: for i in range(schematic.shape[0]): for j in range(schematic.shape[1]): for k in range(schematic.shape[2]): if schematic[i, j, k, 0] > 0: c = self.bid_to_color.get( tuple(schematic[i, j, k, :])) if c: x.append(i) y.append(j) z.append(k) id.append(i + j + k) clrs.append(c) else: for b in schematic: if b[1][0] > 0: c = self.bid_to_color.get(b[1]) if c: x.append(b[0][0]) y.append(b[0][2]) z.append(b[0][1]) id.append(i + j + k) clrs.append(c) # clrs.append(self.bid_to_index[b[1]]) if ptype == "scatter": X = torch.Tensor([x, y, z]).t() if len(clrs) == 0: raise Exception("all 0 input?") colors = (256 * torch.Tensor(clrs)[:, 0:3]).long().numpy() w = self.viz.scatter( X=X, opts={ "markercolor": colors, "markersymbol": "square", "markersize": 15, "title": title, "camera": dict(eye=dict(x=2, y=0.1, z=2)), }, ) # layout = go.Layout(camera =dict(eye=dict(x=2, y=.1, z=2))) self.viz._send({ "win": w, "camera": dict(eye=dict(x=2, y=0.1, z=2)) }) return w else: maxid = max(clrs) clr_set = set(clrs) cmap = [[ c / maxid, "rgb({},{},{})".format( self.index_to_color[c][0], self.index_to_color[c][1], self.index_to_color[c][0], ), ] for c in clr_set] trace1 = go.Volume( x=np.asarray(x).transpose(), y=np.asarray(y).transpose(), z=np.asarray(z).transpose(), value=np.asarray(clrs).transpose(), isomin=0.1, isomax=0.8, colorscale=cmap, opacity=0.1, # needs to be small to see through all surfaces surface_count= 21, # needs to be a large number for good volume rendering ) data = [trace1] layout = go.Layout(margin=dict(l=0, r=0, b=0, t=0)) fig = go.Figure(data=data, layout=layout) self.viz.plotlyplot(fig) return fig
# In[105]: fig = go.Figure(data=go.Streamtube(x=[0, 0, 0], y=[0, 1, 2], z=[0, 0, 0], u=[0, 0, 0], v=[1, 1, 1], w=[0, 0, 0])) pyo.plot(fig, filename="streamtube.html") fig.show() # In[106]: X, Y, Z = np.mgrid[-8:8:40j, -8:8:40j, -8:8:40j] values = np.sin(X * Y * Z) / (X * Y * Z) fig = go.Figure(data=go.Volume( x=X.flatten(), y=Y.flatten(), z=Z.flatten(), value=values.flatten(), isomin=0.1, isomax=0.8, opacity=0.1, # needs to be small to see through all surfaces surface_count=17, # needs to be a large number for good volume rendering )) pyo.plot(fig, filename="volume.html") fig.show() # In[ ]:
def __init__(self, layout, input_data, axes, value_name, cb, show_variances, volume, volume_sampling): super().__init__(input_data, axes, value_name, cb, show_variances, button_options=['X', 'Y', 'Z'], volume=volume) self.cube = None self.volume = volume # Initialise Figure and VBox objects self.fig = None params = { "values": { "cbmin": "min", "cbmax": "max" }, "variances": None } if self.show_variances: params["variances"] = {"cbmin": "min_var", "cbmax": "max_var"} # Set colorbar limits once to keep them constant for slicer # TODO: should there be auto scaling as slider value is changed? for i, (key, val) in enumerate(sorted(params.items())): if val is not None: arr = getattr(self.input_data, key) if self.cb[val["cbmin"]] is not None: val["cmin"] = self.cb[val["cbmin"]] else: val["cmin"] = np.amin(arr[np.where(np.isfinite(arr))]) if self.cb[val["cbmax"]] is not None: val["cmax"] = self.cb[val["cbmax"]] else: val["cmax"] = np.amax(arr[np.where(np.isfinite(arr))]) colorbars = [{ "x": 1.0, "title": value_name, "thicknessmode": 'fraction', "thickness": 0.02 }] # Store min/max for each dimension for invisible scatter self.xminmax = dict() for key, var in self.slider_x.items(): self.xminmax[key] = [var.values[0], var.values[-1]] scatter_x, scatter_y, scatter_z = self.get_outline_as_scatter() # Make a generic volume trace if self.volume: vol_trace = go.Volume(x=[0], y=[0], z=[0], value=[0], opacity=0.1, surface_count=volume_sampling, colorscale=self.cb["name"], showscale=True) xyz = "xyz" if self.show_variances: self.fig = go.FigureWidget( make_subplots(rows=1, cols=2, horizontal_spacing=0.16, specs=[[{ "type": "scene" }, { "type": "scene" }]])) colorbars.append({ "x": 1.0, "title": "Variances", "thicknessmode": 'fraction', "thickness": 0.02 }) colorbars[0]["x"] = -0.1 for i, (key, val) in enumerate(sorted(params.items())): if self.volume: vol_trace["isomin"] = val["cmin"] vol_trace["isomax"] = val["cmax"] vol_trace["meta"] = key vol_trace["colorbar"] = colorbars[i] self.fig.add_trace(vol_trace, row=1, col=i + 1) else: for j in range(3): self.fig.add_trace(go.Surface( cmin=val["cmin"], cmax=val["cmax"], showscale=False, colorscale=self.cb["name"], colorbar=colorbars[i], meta=key, name="slice_{}".format(xyz[j])), row=1, col=i + 1) self.fig.add_trace(go.Scatter3d( x=scatter_x, y=scatter_y, z=scatter_z, marker=dict(cmin=val["cmin"], cmax=val["cmax"], color=np.linspace(val["cmin"], val["cmax"], 8), colorbar=colorbars[i], colorscale=self.cb["name"], showscale=True, opacity=1.0e-6), mode="markers", hoverinfo="none", meta=key, name="scatter"), row=1, col=i + 1) self.fig.update_layout(**layout) else: if self.volume: vol_trace["isomin"] = params["values"]["cmin"] vol_trace["isomax"] = params["values"]["cmax"] vol_trace["meta"] = "values" vol_trace["colorbar"] = colorbars[0] data = [vol_trace] else: data = [ go.Surface(cmin=params["values"]["cmin"], cmax=params["values"]["cmax"], colorscale=self.cb["name"], colorbar=colorbars[0], showscale=False, meta="values", name="slice_{}".format(xyz[j])) for j in range(3) ] data += [ go.Scatter3d(x=scatter_x, y=scatter_y, z=scatter_z, marker=dict(cmin=params["values"]["cmin"], cmax=params["values"]["cmax"], color=np.linspace( params["values"]["cmin"], params["values"]["cmax"], 8), colorbar=colorbars[0], colorscale=self.cb["name"], showscale=True, opacity=1.0e-6), mode="markers", hoverinfo="none", meta="values", name="scatter") ] self.fig = go.FigureWidget(data=data, layout=layout) # Call update_slice once to make the initial image self.update_axes() self.vbox = [self.fig] + self.vbox self.vbox = widgets.VBox(self.vbox) self.vbox.layout.align_items = 'center' return
def activate(self): filename, _ = compat.getsavefilename(parent=self.viewer, basedir="plot.html") # when vispy viewer is in "native aspect ratio" mode, scale axes size by data if self.viewer.state.native_aspect == True: width = self.viewer.state.x_max - self.viewer.state.x_min height = self.viewer.state.y_max - self.viewer.state.y_min depth = self.viewer.state.z_max - self.viewer.state.z_min # otherwise, set all axes to be equal size else: width = 1200 # this 1200 size is arbitrary, could change to any width; just need to scale rest accordingly height = 1200 depth = 1200 # set the aspect ratio of the axes, the tick label size, the axis label sizes, and the axes limits layout = go.Layout( margin=dict(r=50, l=50, b=50, t=50), width=1200, scene=dict( xaxis=dict(title=self.viewer.state.x_att.label, titlefont=dict(family=DEFAULT_FONT, size=20, color='black'), showticklabels=True, backgroundcolor='white', tickfont=dict(family=DEFAULT_FONT, size=12, color='black'), range=[0, self.viewer.state.resolution]), yaxis=dict( title=self.viewer.state.y_att.label, titlefont=dict(family=DEFAULT_FONT, size=20, color='black'), range=[0, self.viewer.state.resolution], showticklabels=True, backgroundcolor='white', tickfont=dict(family=DEFAULT_FONT, size=12, color='black'), ), zaxis=dict( title=self.viewer.state.z_att.label, titlefont=dict(family=DEFAULT_FONT, size=20, color='black'), range=[0, self.viewer.state.resolution], showticklabels=True, backgroundcolor='white', tickfont=dict(family=DEFAULT_FONT, size=12, color='black'), ), aspectratio=dict( x=1 * self.viewer.state.x_stretch, y=height / width * self.viewer.state.y_stretch, z=depth / width * self.viewer.state.z_stretch), aspectmode='manual', ), ) #set up function that returns values of cube at different pixel positions in the fixed resolution grid f = lambda x, y, z, datacube: datacube[z, y, x] bounds = [(self.viewer.state.z_min, self.viewer.state.z_max, self.viewer.state.resolution), (self.viewer.state.y_min, self.viewer.state.y_max, self.viewer.state.resolution), (self.viewer.state.x_min, self.viewer.state.x_max, self.viewer.state.resolution)] #generate array of vertices at fixed resolution X, Y, Z = np.mgrid[0:self.viewer.state.resolution, 0:self.viewer.state.resolution, 0:self.viewer.state.resolution] data = [] for layer_state in self.viewer.state.layers: #check if subset object if isinstance(layer_state.layer, glue.core.subset_group.GroupedSubset): subcube = layer_state.layer.data.compute_fixed_resolution_buffer( target_data=self.viewer.state.reference_data, bounds=bounds, subset_state=layer_state.layer.subset_state) datacube = layer_state.layer.data.compute_fixed_resolution_buffer( target_data=self.viewer.state.reference_data, bounds=bounds, target_cid=layer_state.attribute) datacube = subcube * datacube for i in range(0, len(self.viewer.state.layers)): if self.viewer.state.layers[ i].layer is layer_state.layer.data: isomin = self.viewer.state.layers[i].vmin isomax = self.viewer.state.layers[i].vmax #otherwise a data object else: datacube = layer_state.layer.compute_fixed_resolution_buffer( target_data=self.viewer.state.reference_data, bounds=bounds, target_cid=layer_state.attribute) isomin = layer_state.vmin isomax = layer_state.vmax #fetch values of cube at different coordinate combination values = f(X.flatten().astype(int), Y.flatten().astype(int), Z.flatten().astype(int), datacube.copy()) voltrace = go.Volume( x=X.flatten().astype(int), y=Y.flatten().astype(int), z=Z.flatten().astype(int), value=values.flatten(), flatshading=True, opacity=0.2, isomin=isomin, showscale=False, isomax=isomax, colorscale=[[0, 'white'], [1., layer_state.color]], opacityscale='max', reversescale=False, surface=dict(show=True, count=25), spaceframe=dict(show=True), #, contour=dict(show=False, width=4)) data.append(voltrace) fig = go.Figure(data=data, layout=layout) plot(fig, filename=filename, auto_open=False)
def volume(self, x=None, y=None, z=None, vol=None, w=700, h=700, res=50, grid=True, pane_fill=None, prune=None, x_slice=True, x_center=None, x_scale=1, x_lim=None, y_slice=True, y_center=-3.5, y_scale=1, y_lim=None, z_slice=True, z_center=None, z_scale=1, z_lim=None, norm=None, cb_labelpad=10, cb_nticks=10, cb_x=None, cb_y=None, cb_title=None, cb_length=0.75, cb_outlinecolor=None, cb_outlinewidth=1, cb_tickfontsize=10, plot_title='Airstream', title_bold=True, title_size=20, title_pad=5, title_y=0.85, x_label='x', xaxis_bold=False, xaxis_labelpad=5, xlabel_rotation=None, x_tick_number=10, y_label='y', yaxis_bold=False, yaxis_labelpad=5, ylabel_rotation=None, y_tick_number=10, z_label='z', zaxis_bold=False, zaxis_labelpad=5, zlabel_rotation=None, z_tick_number=10, axis_label_size=20, tick_color=None, tick_label_size=12, tick_label_pad=5, xtick_rotation=None, ytick_rotation=None, ztick_rotation=None, floating_text=None, filename=None): # Colorbar parameters self.cb_outlinecolor = cb_outlinecolor if cb_outlinecolor is not None else self.color2 self.cb_outlinewidth = cb_outlinewidth self.cb_length = cb_length self.cb_title = cb_title self.cb_x = cb_x self.cb_y = cb_y self.cb_xpad = cb_labelpad self.cb_nticks = cb_nticks self.cb_tickfontsize = cb_tickfontsize # Mock plot if isinstance(x, type(None)) and isinstance(y, type(None)) and isinstance(z, type(None)) and isinstance(vol, type(None)): np.random.seed(0) def f(x, y, z): return x+y+z x, y, z, vol = Data3D().volumetric(f, u0=0, un=1, v0=0, vn=1, w0=0, wn=1, n=100) # Individual axis setup axis = dict(showbackground=True, backgroundcolor=pane_fill, showgrid=grid, gridcolor=self.color2, zerolinecolor=self.color2, tickfont={'family': self.font, 'size': tick_label_size, 'color': tick_color}, titlefont={'family': self.font, 'size': axis_label_size}, ) # Layout layout = go.Layout( width=w, height=h, scene=dict(xaxis=dict(axis, range=x_lim, tickangle=xtick_rotation, nticks=x_tick_number, title='<b>'+x_label+'</b>' if xaxis_bold is True else x_label), yaxis=dict(axis, range=y_lim, tickangle=ytick_rotation, nticks=y_tick_number, title='<b>'+y_label+'</b>' if yaxis_bold is True else y_label), zaxis=dict(axis, range=z_lim, tickangle=ztick_rotation, nticks=z_tick_number, title='<b>'+z_label+'</b>' if zaxis_bold is True else z_label), aspectratio=dict(x=x_scale, y=y_scale, z=z_scale) ), template=self.template ) # Plot fig = go.Figure(data=go.Volume(x=x, y=y, z=z, value=vol, isomin=0.2, isomax=0.7, opacity=0.1, surface_count=25, colorbar=dict(len=self.cb_length, x=self.cb_x, xpad=self.cb_xpad, y=self.cb_y, outlinecolor=self.cb_outlinecolor, outlinewidth=self.cb_outlinewidth, tick0=0, dtick=0.5, ticklen=5, tickwidth=1, tickfont=dict(size=self.cb_tickfontsize, color=self.color, family=self.font), title=self.cb_title) ), layout=layout) # Makeup fig.update_layout( title={'text': '<b>'+plot_title+'<b>' if title_bold is True else plot_title, 'x': 0.5, 'y': title_y, 'xanchor': 'center', 'yanchor': 'top'}, font=dict( family=self.font, size=title_size, color=self.color, ) ) fig.show() if not isinstance(filename, type(None)): self.save(fig=fig, filename=filename)