def createFigureWidget(self): dimensions = self.dimensions data_lines = [] i = 0 if self.only_subsets == False: colors = [i for r in range(self.data.size)] colorscale = [[0, '#EEEEEE']] else: colors = [] colorscale = [] i = -1 for sset in self.data.subsets: i = i + 1 tmplist = [i for r in range(len(sset.to_index_list()))] colors.extend(tmplist) colorscale.append([i, sset.style.color]) t_color = len(colorscale) if (t_color > 1): for c in colorscale: c[0] = c[0] / (t_color - 1) else: colorscale = [[0, '#EEEEEE'], [1, '#EEEEEE']] for dimension in dimensions: line = {} if hasattr(self.data[dimension].flatten(), 'codes'): line['values'] = self.data[dimension].flatten().codes.tolist() tickvals, tickmask = np.unique( self.data[dimension].flatten().codes, return_index=True) ticktext = self.data[dimension][tickmask] line['tickvals'] = tickvals.tolist() line['ticktext'] = ticktext.tolist() else: line['values'] = self.data[dimension].flatten().tolist() line['label'] = dimension for sset in self.data.subsets: if hasattr(sset[dimension].flatten(), 'codes'): tmplist = sset[dimension].codes.tolist() else: tmplist = sset[dimension].tolist() line['values'].extend(tmplist) data_lines.append(line) data = [ go.Parcoords(line=dict(color=colors, colorscale=colorscale), dimensions=data_lines), ] layout = { 'title': self.options['title'].value, 'xaxis': { 'title': self.options['xaxis'].value, }, 'yaxis': { 'title': self.options['yaxis'].value, } } return FigureWidget(data=data, layout=layout)
def __init__(self, xe, xc, ye, yc, values, variances, resolution, cb, plot_type, title, contours): self.xe = xe self.xc = xc self.ye = ye self.yc = yc self.values = values self.variances = variances self.resolution = resolution self.cb = cb self.plot_type = plot_type self.title = title self.contours = contours self.nx = len(self.xe) self.ny = len(self.ye) self.val_range = np.zeros([4], dtype=np.float64) self.var_range = np.zeros([4], dtype=np.float64) self.fig_val = FigureWidget() if self.variances is not None: self.fig_var = FigureWidget() self.hbox = HBox([self.fig_val, self.fig_var]) else: self.fig_var = None self.hbox = None # Make an initial low-resolution sampling of the image for plotting self.update_values(layout=None, x_range=[self.xe[0], self.xe[-1]], y_range=[self.ye[0], self.ye[-1]]) # Add a callback to update the view area self.fig_val.layout.on_change( self.update_values, 'xaxis.range', 'yaxis.range') if self.variances is not None: self.fig_var.layout.on_change( self.update_variances, 'xaxis.range', 'yaxis.range') return
def __init__(self, figure=None): self._figure = figure or FigureWidget() self._layout = None self._trajectories = [] # type: List[Trajectory] self._attractor = None self._attractor_radius = np.inf * u.km self._color_cycle = cycle(plotly.colors.DEFAULT_PLOTLY_COLORS)
def createFigureWidget(self, x_id, y_id_list): traces = [] alpha_min, alpha_max, alpha_delta = self.getDeltaFunction(len(y_id_list)) alpha_val = alpha_max x_values = self.data[x_id].flatten() x_sort = x_values.argsort() for y_id in y_id_list: y_values = self.data[y_id].flatten() color = "#444444" color = 'rgba'+str(self.getDeltaColor(color, alpha_val)) trace = { 'type': "scattergl", 'mode': self.options['marker_type'].value, 'name': self.data.label + "_" + y_id, 'line' : { 'width' : self.options['line_width'].value, 'color' : color }, 'x': x_values[x_sort], 'y': y_values[x_sort], } if self.only_subsets == False: traces.append(trace) alpha_val = alpha_val - alpha_delta for sset in self.data.subsets: alpha_val = alpha_max x_values = sset[x_id].flatten() x_sort = x_values.argsort() for i, y_id in enumerate(y_id_list): y_values = sset[y_id].flatten() color = sset.style.color color = 'rgba'+str(self.getDeltaColor(color, alpha_val, i)) trace = { 'type': "scattergl", 'mode': self.options['marker_type'].value, 'name': sset.label + "_" + y_id, 'line' : { 'width' : self.options['line_width'].value, 'color' : color}, 'x': x_values[x_sort], 'y': y_values[x_sort], } traces.append(trace) alpha_val = alpha_val - alpha_delta layout = { 'margin' : {'l':50,'r':0,'b':50,'t':30 }, 'xaxis': { 'autorange' : True, 'zeroline': True, 'title' : self.options['xaxis'].value, 'type' : self.options['xscale'].value }, 'yaxis': { 'autorange':True, 'zeroline': True, 'title' : self.options['yaxis'].value, 'type' : self.options['yscale'].value }, 'showlegend': True, } return FigureWidget({ 'data': traces, 'layout': layout })
def show_sky_coords(self, font_size=16, width=500, height=500, y_xaxis=-0.15, x_yaxis=-0.2, title=None, margins=None, **kwargs): """ Interactive RA-DEC plot """ self.set_marker(**kwargs) fig = FigureWidget( **{ 'data': [{ 'x': self.cat.ra, 'y': self.cat.dec, 'marker': self.marker, 'mode': 'markers', 'type': 'scatter' }], 'layout': { 'dragmode': 'pan', 'width': width, 'height': height, 'font_size': font_size } }) xtit = text_annote(text='$\\text{R.A [}^\circ]$', x=0.5, y=y_xaxis, font_size=font_size * 1.2) ytit = text_annote(text='$\\text{Dec [}^\circ]$', x=x_yaxis, y=0.5, font_size=font_size * 1.2, textangle=-90) fig = self.set_fig_show( fig, margins=margins, annotations=[xtit, ytit], title=title, new_xrange=[self.cat.ra.max(), self.cat.ra.min()]) if hasattr(self, 'control'): self.set_marker_control() fig.add_trace( go.Scatter(x=self.control.cat.ra, y=self.control.cat.dec, marker=self.marker_control, mode='markers')) fig.update_layout(showlegend=False) self.fig_sky = fig
def show_properm(self, font_size=16, width=500, height=500, y_xaxis=-0.15, x_yaxis=-0.2, title=None, margins=None, **kwargs): """ Interactive Proper-Motions plot """ self.set_marker(**kwargs) fig = FigureWidget( **{ 'data': [{ 'x': self.cat.pmra, 'y': self.cat.pmdec, 'marker': self.marker, 'mode': 'markers', 'type': 'scatter' }], 'layout': { 'dragmode': 'pan', 'width': width, 'height': height, 'font_size': font_size } }) xtit = text_annote(text='$\\text{pmra [mas yr}^{-1}]$', x=0.5, y=y_xaxis, font_size=font_size * 1.2) ytit = text_annote(text='$\\text{pmdec [mas yr}^{-1}]$', x=x_yaxis, y=0.5, font_size=font_size * 1.2, textangle=-90) fig = self.set_fig_show(fig, margins=margins, annotations=[xtit, ytit], title=title) if hasattr(self, 'control'): self.set_marker_control() fig.add_trace( go.Scatter(x=self.control.cat.pmra, y=self.control.cat.pmdec, marker=self.marker_control, mode='markers')) fig.update_layout(showlegend=False) self.fig_properm = fig
def show_hist_dist(self, font_size=16, width=500, height=500, y_xaxis=-0.15, x_yaxis=-0.2, title=None, margins=None, **kwargs): """ Interactive Histogram (distances) plot """ self.set_marker(hist_marker=True, **kwargs) fig = FigureWidget( **{ 'data': [{ 'x': self.cat.distance, 'marker': self.marker, 'type': 'histogram' }], 'layout': { 'dragmode': 'pan', 'width': width, 'height': height, 'font_size': font_size } }) xtit = text_annote(text='Distance [pc]', x=0.5, y=y_xaxis, font_size=font_size * 1.2) ytit = text_annote(text='# Objects', x=x_yaxis, y=0.5, font_size=font_size * 1.2, textangle=-90) fig = self.set_fig_show(fig, margins=margins, annotations=[xtit, ytit], title=title) if hasattr(self, 'control'): marker_control_hist = self.marker.copy() marker_control_hist['color'] = self.control.color fig.add_trace( go.Histogram(x=self.control.cat.distance, marker=marker_control_hist)) fig.update_layout(barmode='overlay', showlegend=False) self.fig_hist_dist = fig
def plot_waterfall(input_data, dim=None, name=None, axes=None, filename=None, config=None, **kwargs): """ Make a 3D waterfall plot """ # Get coordinates axes and dimensions coords = input_data.coords labels = input_data.labels xcoord, ycoord, xe, ye, xc, yc, xlabs, ylabs, zlabs = \ process_dimensions(input_data=input_data, coords=coords, labels=labels, axes=axes) data = [] z = input_data.values if (zlabs[0] == xlabs[0]) and (zlabs[1] == ylabs[0]): z = z.T zlabs = [ylabs[0], xlabs[0]] pdict = dict(type='scatter3d', mode='lines', line=dict(width=5)) adict = dict(z=1) if dim is None: dim = zlabs[0] if dim == zlabs[0]: for i in range(len(yc)): idict = pdict.copy() idict["x"] = xc idict["y"] = [yc[i]] * len(xc) idict["z"] = z[i, :] data.append(idict) adict["x"] = 3 adict["y"] = 1 elif dim == zlabs[1]: for i in range(len(xc)): idict = pdict.copy() idict["x"] = [xc[i]] * len(yc) idict["y"] = yc idict["z"] = z[:, i] data.append(idict) adict["x"] = 1 adict["y"] = 3 else: raise RuntimeError("Something went wrong in plot_waterfall. The " "waterfall dimension is not recognised.") layout = dict( scene=dict( xaxis=dict( title=xcoord), yaxis=dict( title=ycoord), zaxis=dict( title=axis_label(var=input_data, name=name)), aspectmode='manual', aspectratio=adict), showlegend=False, height=config.height) fig = FigureWidget(data=data, layout=layout) if filename is not None: write_image(fig=fig, file=filename) else: display(fig) return
def plot_1d(input_data, logx=False, logy=False, logxy=False, axes=None, color=None, filename=None, config=None): """ Plot a 1D spectrum. Input is a dictionary containing a list of DataProxy. If the coordinate of the x-axis contains bin edges, then a bar plot is made. TODO: find a more general way of handling arguments to be sent to plotly, probably via a dictionay of arguments """ data = [] color_count = 0 for name, var in input_data.items(): # TODO: find a better way of getting x by accessing the dimension of # the coordinate directly instead of iterating over all of them coords = var.coords for c in coords: x = coords[c[0]].values xlab = axis_label(coords[c[0]]) y = var.values ylab = axis_label(var=var, name=name) nx = x.shape[0] ny = y.shape[0] histogram = False if nx == ny + 1: x, w = edges_to_centers(x) histogram = True # Define trace trace = dict(x=x, y=y, name=ylab) if histogram: trace["type"] = 'bar' trace["marker"] = dict(opacity=0.6, line=dict(width=0)) trace["width"] = w else: trace["type"] = 'scatter' if color is not None: if "marker" not in trace.keys(): trace["marker"] = dict() trace["marker"]["color"] = color[color_count] color_count += 1 # Include variance if present if var.variances is not None: trace["error_y"] = dict( type='data', array=np.sqrt(var.variances), visible=True) data.append(trace) layout = dict( xaxis=dict(title=xlab), yaxis=dict(), showlegend=True, legend=dict(x=0.0, y=1.15, orientation="h"), height=config.height ) if histogram: layout["barmode"] = "overlay" if logx or logxy: layout["xaxis"]["type"] = "log" if logy or logxy: layout["yaxis"]["type"] = "log" fig = FigureWidget(data=data, layout=layout) if filename is not None: write_image(fig=fig, file=filename) else: display(fig) return
class ImageViewer: def __init__(self, xe, xc, ye, yc, values, variances, resolution, cb, plot_type, title, contours): self.xe = xe self.xc = xc self.ye = ye self.yc = yc self.values = values self.variances = variances self.resolution = resolution self.cb = cb self.plot_type = plot_type self.title = title self.contours = contours self.nx = len(self.xe) self.ny = len(self.ye) self.val_range = np.zeros([4], dtype=np.float64) self.var_range = np.zeros([4], dtype=np.float64) self.fig_val = FigureWidget() if self.variances is not None: self.fig_var = FigureWidget() self.hbox = HBox([self.fig_val, self.fig_var]) else: self.fig_var = None self.hbox = None # Make an initial low-resolution sampling of the image for plotting self.update_values(layout=None, x_range=[self.xe[0], self.xe[-1]], y_range=[self.ye[0], self.ye[-1]]) # Add a callback to update the view area self.fig_val.layout.on_change( self.update_values, 'xaxis.range', 'yaxis.range') if self.variances is not None: self.fig_var.layout.on_change( self.update_variances, 'xaxis.range', 'yaxis.range') return def update_values(self, layout, x_range, y_range, origin=None, res=None): ranges = np.array([x_range[0], x_range[1], y_range[0], y_range[1]], copy=True) if not np.array_equal(self.val_range, ranges): self.val_range = ranges.copy() if res is None: res = self.resample_image(x_range, y_range) # The local values array values_loc = np.zeros([res.nye - 1, res.nxe - 1]) values_loc[res.jmin:res.nye - res.jmax - 1, res.imin:res.nxe - res.imax - 1] = \ self.resample_arrays(self.values, res) # Update figure data dict res.datadict["z"] = values_loc res.datadict["colorbar"] = {"title": {"text": self.title, "side": "right"}} # Update the figure updatedict = {'data': [res.datadict]} if origin is not None: # Make a copy of the layout to update it all at once layoutdict = Layout(self.fig_var.layout) updatedict["layout"] = layoutdict self.fig_val.update(updatedict) if (origin is None) and (self.variances is not None): self.update_variances(layout, x_range, y_range, 'values', res) return def update_variances(self, layout, x_range, y_range, origin=None, res=None): ranges = np.array([x_range[0], x_range[1], y_range[0], y_range[1]], copy=True) if not np.array_equal(self.var_range, ranges): self.var_range = ranges.copy() if res is None: res = self.resample_image(x_range, y_range) # The local variances array variances_loc = np.zeros([res.nye - 1, res.nxe - 1]) variances_loc[res.jmin:res.nye - res.jmax - 1, res.imin:res.nxe - res.imax - 1] = \ self.resample_arrays(self.variances, res) # Update figure data dict res.datadict["z"] = variances_loc res.datadict["colorbar"] = {"title": {"text": "std. dev", "side": "right"}} # Update the figure updatedict = {'data': [res.datadict]} if origin is not None: # Make a copy of the layout to update it all at once layoutdict = Layout(self.fig_val.layout) updatedict["layout"] = layoutdict self.fig_var.update(updatedict) if origin is None: self.update_values(layout, x_range, y_range, "variances", res) return def resample_image(self, x_range, y_range): # Create a namedtuple to hold the results out = namedtuple("out", ['nx_view', 'ny_view', 'xmin', 'xmax', 'ymin', 'ymax', 'xe_loc', 'ye_loc', 'nxe', 'nye', 'imin', 'imax', 'jmin', 'jmax', 'datadict']) # Find indices of xe and ye that are shown in current range x_in_range = np.where( np.logical_and( self.xe >= x_range[0], self.xe <= x_range[1])) y_in_range = np.where( np.logical_and( self.ye >= y_range[0], self.ye <= y_range[1])) # xmin, xmax... here are array indices, not float coordinates out.xmin = x_in_range[0][0] out.xmax = x_in_range[0][-1] out.ymin = y_in_range[0][0] out.ymax = y_in_range[0][-1] # here we perform a trick so that the edges of the displayed image # is not greyed out if the zoom area slices a pixel in half, only # the pixel inside the view area will be shown and the outer edge # between that last pixel edge and the edge of the view frame area # will be empty. So we extend the selected area with an additional # pixel, if the selected area is inside the global limits of the # full resolution array. out.xmin -= int(out.xmin > 0) out.xmax += int(out.xmax < self.nx - 1) out.ymin -= int(out.ymin > 0) out.ymax += int(out.ymax < self.ny - 1) # Part of the global coordinate arrays that are inside the viewing # area xview = self.xe[out.xmin:out.xmax + 1] yview = self.ye[out.ymin:out.ymax + 1] # Count the number of pixels in the current view out.nx_view = out.xmax - out.xmin out.ny_view = out.ymax - out.ymin # Define x and y edges for histogramming # If the number of pixels in the view area is larger than the # maximum allowed resolution we create some custom pixels if out.nx_view > self.resolution: out.xe_loc = np.linspace(xview[0], xview[-1], self.resolution + 1) else: out.xe_loc = xview if out.ny_view > self.resolution: out.ye_loc = np.linspace(yview[0], yview[-1], self.resolution + 1) else: out.ye_loc = yview # Here we perform another trick. If we plot simply the local arrays # in plotly, the reset axes or home functionality will be lost # because plotly will now think that the data that exists is only # the small window shown after a zoom. So we add a one-pixel # padding area to the local z array. The size of that padding # extends from the edges of the initial full resolution array # (e.g. x=0, y=0) up to the edge of the view area. These large # (and probably elongated) pixels add very little data and will not # show in the view area but allow plotly to recover the full axes # limits if we double-click on the plot xc_loc = edges_to_centers(out.xe_loc)[0] yc_loc = edges_to_centers(out.ye_loc)[0] if out.xmin > 0: out.xe_loc = np.concatenate([self.xe[0:1], out.xe_loc]) xc_loc = np.concatenate([self.xc[0:1], xc_loc]) if out.xmax < self.nx - 1: out.xe_loc = np.concatenate([out.xe_loc, self.xe[-1:]]) xc_loc = np.concatenate([xc_loc, self.xc[-1:]]) if out.ymin > 0: out.ye_loc = np.concatenate([self.ye[0:1], out.ye_loc]) yc_loc = np.concatenate([self.yc[0:1], yc_loc]) if out.ymax < self.ny - 1: out.ye_loc = np.concatenate([out.ye_loc, self.ye[-1:]]) yc_loc = np.concatenate([yc_loc, self.yc[-1:]]) out.imin = int(out.xmin > 0) out.imax = int(out.xmax < self.nx - 1) out.jmin = int(out.ymin > 0) out.jmax = int(out.ymax < self.ny - 1) out.nxe = len(out.xe_loc) out.nye = len(out.ye_loc) # The 'data' dictionary out.datadict = dict(type=self.plot_type, zmin=self.cb["min"], zmax=self.cb["max"], colorscale=self.cb["name"]) if self.contours: out.datadict["x"] = xc_loc out.datadict["y"] = yc_loc else: out.datadict["x"] = out.xe_loc out.datadict["y"] = out.ye_loc return out def resample_arrays(self, array, res): # Optimize if no re-sampling is required if (res.nx_view < self.resolution) and \ (res.ny_view < self.resolution): return array[res.ymin:res.ymax, res.xmin:res.xmax] else: xg, yg = np.meshgrid(self.xc[res.xmin:res.xmax], self.yc[res.ymin:res.ymax]) xv = np.ravel(xg) yv = np.ravel(yg) # Histogram the data to make a low-resolution image # Using weights in the second histogram allows us to then do # z1/z0 to obtain the averaged data inside the coarse pixels array0, yedges, xedges = np.histogram2d( yv, xv, bins=(res.ye_loc[res.jmin:res.nye - res.jmax], res.xe_loc[res.imin:res.nxe - res.imax])) array1, yedges, xedges = np.histogram2d( yv, xv, bins=(res.ye_loc[res.jmin:res.nye - res.jmax], res.xe_loc[res.imin:res.nxe - res.imax]), weights=np.ravel(array[res.ymin:res.ymax, res.xmin:res.xmax])) return array1 / array0
def show(self, title='', xlabel='', ylabel='', xaxis=True, yaxis=True, xticks=True, yticks=True, legend=True, grid=True, **kwargs): # get before wrapper strips tdata = [] ldata = {} y2_count = sum([1 for (_, _, a, _) in self.figures if a == 'right']) y2s = 2 y2p = .05 / y2_count if y2_count > 0 else 0 y2_base = .95 if y2_count > 0 else 1.0 for col, figure, axis, color in self.figures: for trace in figure['data']: if axis == 'right': trace['yaxis'] = 'y%d' % y2s trace['xaxis'] = 'x' else: trace['yaxis'] = 'y1' trace['xaxis'] = 'x' tdata.append(trace) if axis == 'right': ldata['yaxis%d' % y2s] = dict(side='right', overlaying='y', color=color, position=y2_base) y2s += 1 y2_base += y2p else: ldata['yaxis1'] = dict(side='left', ) ldata['xaxis'] = dict(domain=[0, 0.95]) ldata['shapes'] = [] for line in self.hlines: ldata['shapes'].append({ 'x0': 0, 'x1': 1, 'y0': line[0], 'y1': line[0], 'line': { 'color': line[1], 'width': 1, 'dash': 'solid' }, 'xref': 'paper', 'yref': 'y', 'type': 'line' }) for line in self.vlines: ldata['shapes'].append({ 'y0': 0, 'y1': 1, 'x0': line[0], 'x1': line[0], 'line': { 'color': line[1], 'width': 1, 'dash': 'solid' }, 'xref': 'x', 'yref': 'paper', 'type': 'line' }) for line in self.hspans: col = to_rgb(line[2]) r = str(round(col[0] * 255)) g = str(round(col[1] * 255)) b = str(round(col[2] * 255)) ldata['shapes'].append({ 'x0': 0, 'x1': 1, 'y0': line[1], 'y1': line[0], 'line': { 'color': line[2], 'width': 1, 'dash': 'solid' }, 'xref': 'paper', 'yref': 'y', 'type': 'rect', 'fillcolor': 'rgba(' + r + ',' + g + ',' + b + ',.5)' }) for line in self.vspans: col = to_rgb(line[2]) r = str(round(col[0] * 255)) g = str(round(col[1] * 255)) b = str(round(col[2] * 255)) ldata['shapes'].append({ 'y0': 0, 'y1': 1, 'x0': line[1], 'x1': line[0], 'line': { 'color': line[2], 'width': 1, 'dash': 'solid' }, 'xref': 'x', 'yref': 'paper', 'type': 'rect', 'fillcolor': 'rgba(' + r + ',' + g + ',' + b + ',.5)' }) if title: ldata['title'] = title if ylabel: for k in ldata: if 'yaxis' in k: ldata[k] = dict( title=ylabel, titlefont=dict( family='Courier New, monospace', size=18, color='#7f7f7f', ), showgrid=grid, showline=yaxis, showticklabels=yticks, ) if xlabel: for k in ldata: if 'xaxis' in k: ldata['xaxis'] = dict( title=xlabel, titlefont=dict( family='Courier New, monospace', size=18, color='#7f7f7f', ), showgrid=grid, showline=xaxis, showticklabels=xticks, ) ldata['showlegend'] = legend x_size = self.size[0] if self.size[0] > 100 else self.size[0] * 100 y_size = self.size[1] if self.size[1] > 100 else self.size[1] * 100 ldata['width'], ldata['height'] = x_size, y_size return FigureWidget(data=tdata, layout=ldata)
def createFigureWidget(self, x_id, y_id_list): traces = [] alpha_min, alpha_max, alpha_delta = self.getDeltaFunction(len(y_id_list)) alpha_val = alpha_max xtickmode = "auto" xtickvals = None xticktext = None if hasattr(self.data[x_id].flatten(), 'codes'): x_val = self.data[x_id].flatten().codes.tolist() tickvals, tickmask = np.unique(self.data[x_id].flatten().codes, return_index=True) ticktext = self.data[x_id][tickmask] xtickmode = "array" xtickvals = tickvals.tolist() xticktext = ticktext.tolist() else: x_val = self.data[x_id].flatten() for y_id in y_id_list: color = "#444444" color = 'rgba'+str(self.getDeltaColor(color, alpha_val)) if hasattr(self.data[y_id].flatten(), 'codes'): y_val = self.data[y_id].flatten().codes.tolist() else: y_val = self.data[y_id].flatten() trace = { 'type': "scattergl", 'mode': "markers", 'name': self.data.label + "_" + y_id, 'marker': dict({ 'symbol':'circle', 'size': self.options['marker_size'].value, 'color': color, 'line' : { 'width' : self.options['line_width'].value, 'color' : color } }), 'x': x_val, 'y': y_val, } if self.only_subsets == False: traces.append(trace) alpha_val = alpha_val - alpha_delta for sset in self.data.subsets: alpha_val = alpha_max if hasattr(sset[x_id].flatten(), 'codes'): x_val = sset[x_id].flatten().codes.tolist() else: x_val = sset[x_id].flatten() for i, y_id in enumerate(y_id_list): y_val = sset[y_id].flatten().astype('float') color = sset.style.color color = 'rgba'+str(self.getDeltaColor(color, alpha_val, i)) trace = { 'type': "scattergl", 'mode': "markers", 'name': sset.label + "_" + y_id, 'marker': dict({ 'symbol':'circle', 'size': self.focused_size_marker, 'color': color, 'line' : { 'width' : self.options['line_width'].value, 'color' : color} }), 'selected':{'marker':{'color':color, 'size': self.options['marker_size'].value}}, 'unselected':{'marker':{'color':color, 'size': self.options['marker_size'].value}}, 'x': x_val, 'y': y_val, } traces.append(trace) alpha_val = alpha_val - alpha_delta layout = { 'title' : self.options['title'].value, 'margin' : { 'l':self.margins['left'].value, 'r':self.margins['right'].value, 'b':self.margins['bottom'].value, 't':self.margins['top'].value }, 'xaxis': { 'autorange' : True, 'zeroline': True, 'title' : self.options['xaxis'].value, 'type' : self.options['xscale'].value, 'tickmode' : xtickmode, 'tickvals' : xtickvals, 'ticktext' : xticktext, }, 'yaxis': { 'autorange':True, 'zeroline': True, 'title' : self.options['yaxis'].value, 'type' : self.options['yscale'].value }, 'showlegend': True, } return FigureWidget({ 'data': traces, 'layout': layout })
def createFigureWidget(self): x_id = self.dimensions[0] y_id = self.dimensions[1] z_id = self.dimensions[2] x_value = self.data[x_id].flatten().astype('float') y_value = self.data[y_id].flatten().astype('float') x_value, x_inv = np.unique(x_value, return_inverse=True) y_value, y_inv = np.unique(y_value, return_inverse=True) try: z_value = np.reshape(self.data[z_id].flatten(), (len(x_value), len(y_value))) except: t_value = self.data[z_id].flatten() x_value = np.sort(x_value) y_value = np.sort(y_value) z_value = np.zeros((len(x_value), len(y_value))) for i, value in enumerate(t_value): z_value[x_inv[i]][y_inv[i]] = value #with self.debug: # print (x_value,y_value,z_value) traces = [] trace = { 'type': "contour", 'colorscale': self.options['color_scale'].value, 'showlegend': False, 'autocontour': False, 'ncontours': 1, 'contours': { 'coloring': 'heatmap' }, 'x': x_value.tolist(), 'y': y_value.tolist(), 'z': z_value.tolist(), 'zauto': False, 'zmin': self.options['color_range_min'].value, 'zmax': self.options['color_range_max'].value, } if self.only_subsets == False: traces.append(trace) for sset in self.data.subsets: color = sset.style.color color = 'rgba' + str(self.getDeltaColor(color, 0.6)) trace = { 'type': "scattergl", 'mode': "markers", 'name': sset.label + "_" + y_id, 'marker': dict({ 'symbol': 'circle', 'size': self.options['marker_size'].value, 'color': color, 'line': { 'width': self.options['line_width'].value, 'color': color } }), 'selected': { 'marker': { 'color': color, 'size': self.options['marker_size'].value } }, 'unselected': { 'marker': { 'color': color, 'size': self.options['marker_size'].value } }, 'x': sset[x_id].flatten(), 'y': sset[y_id].flatten(), } traces.append(trace) layout = { 'title': self.options['title'].value, 'margin': { 'l': 50, 'r': 0, 'b': 50, 't': 30 }, 'xaxis': { 'autorange': True, 'zeroline': True, 'title': self.options['xaxis'].value, }, 'yaxis': { 'autorange': True, 'zeroline': True, 'title': self.options['yaxis'].value, }, 'showlegend': True, } return FigureWidget({'data': traces, 'layout': layout})
def createFigureWidget(self, x_id, y_id, z_id): traces = [] color = "#444444" color = 'rgba' + str(self.getDeltaColor(color, .8)) trace = { 'type': "scatter3d", 'mode': "markers", 'name': self.data.label, 'marker': dict({ 'symbol': 'circle', 'size': self.options['marker_size'].value, 'color': color, }), 'x': self.data[x_id].flatten(), 'y': self.data[y_id].flatten(), 'z': self.data[z_id].flatten(), } if self.only_subsets == False: traces.append(trace) for sset in self.data.subsets: color = sset.style.color color = 'rgba' + str(self.getDeltaColor(color, .8)) trace = { 'type': "scatter3d", 'mode': "markers", 'name': sset.label, 'marker': dict({ 'symbol': 'circle', 'size': self.options['marker_size'].value, 'color': color, }), 'x': sset[x_id].flatten(), 'y': sset[y_id].flatten(), 'z': sset[z_id].flatten(), } traces.append(trace) layout = { 'margin': { 'l': 0, 'r': 0, 'b': 0, 't': 30 }, 'scene': { 'xaxis': { 'title': self.options['xaxis'].value }, 'yaxis': { 'title': self.options['yaxis'].value }, 'zaxis': { 'title': self.options['zaxis'].value } } } return FigureWidget({'data': traces, 'layout': layout})
def show_3D_space(self, font_size=16, width=1200, height=800, y_xaxis=-0.15, x_yaxis=-0.2, title=None, margins=None, **kwargs): """ Interactive Proper-Motions plot """ self.set_marker(**kwargs) fig = FigureWidget( **{ 'data': [{ 'x': self.cat.X_gal, 'y': self.cat.Y_gal, 'z': self.cat.Z_gal, 'marker': self.marker, 'mode': 'markers', 'type': 'scatter3d' }], 'layout': { 'dragmode': 'pan', 'width': width, 'height': height, 'font_size': font_size, 'showlegend': False } }) if hasattr(self, 'control'): self.set_marker_control() fig.add_trace( go.Scatter3d({ 'x': self.control.cat.X_gal, 'y': self.control.cat.Y_gal, 'z': self.control.cat.Z_gal, 'mode': 'markers', 'marker': self.marker_control })) if hasattr(self, 'cat_subsamp'): marker = self.marker marker['color'] = self.color_high fig.add_trace( go.Scatter3d({ 'x': self.cat_subsamp.X_gal, 'y': self.cat_subsamp.Y_gal, 'z': self.cat_subsamp.Z_gal, 'mode': 'markers', 'marker': marker })) fig.update_layout(scene=dict(xaxis_title='X_Gal [pc]', yaxis_title='Y_Gal [pc]', zaxis_title='Z_Gal [pc]')) fig = self.set_fig_show(fig, margins=margins, title=title) self.fig_3D = fig
def __init__(self, plotly_data, plotly_layout, input_data, axes, value_name, cb): # Make a copy of the input data - Needed? self.input_data = input_data # Get the dimensions of the image to be displayed self.coords = self.input_data.coords self.labels = self.input_data.labels _, self.xcoord = get_coord_array(self.coords, self.labels, axes[-1]) _, self.ycoord = get_coord_array(self.coords, self.labels, axes[-2]) self.xlabs = self.xcoord.dims self.ylabs = self.ycoord.dims self.labels = self.input_data.dims self.shapes = dict(zip(self.labels, self.input_data.shape)) # Size of the slider coordinate arrays self.slider_nx = [] # Save dimensions tags for sliders, e.g. Dim.X self.slider_dims = [] # Store coordinates of dimensions that will be in sliders self.slider_x = [] for ax in axes[:-2]: self.slider_dims.append(ax) self.slider_nx.append(self.shapes[ax]) self.slider_x.append(self.coords[ax].values) self.nslices = len(self.slider_dims) # Initialise Figure and VBox objects self.fig = FigureWidget(data=plotly_data, layout=plotly_layout) self.vbox = self.fig, # Initialise slider and label containers self.lab = [] self.slider = [] # Collect the remaining arguments self.value_name = value_name self.cb = cb # Default starting index for slider indx = 0 # Now begin loop to construct sliders for i in range(len(self.slider_nx)): # Add a label widget to display the value of the z coordinate self.lab.append(Label(value=str(self.slider_x[i][indx]))) # Add an IntSlider to slide along the z dimension of the array self.slider.append(IntSlider( value=indx, min=0, max=self.slider_nx[i] - 1, step=1, description="", continuous_update=True, readout=False )) # Add an observer to the slider self.slider[i].observe(self.update_slice, names="value") # Add coordinate name and unit title = Label(value=axis_label(self.coords[self.slider_dims[i]])) self.vbox += (HBox([title, self.slider[i], self.lab[i]]),) # Call update_slice once to make the initial image self.update_slice(0) self.vbox = VBox(self.vbox) self.vbox.layout.align_items = 'center' return
def createFigureWidget(self, x_id, y_id): heatmap, xedges, yedges = np.histogram2d(self.data[x_id].flatten().astype('float'), self.data[y_id].flatten().astype('float'), bins=self.options['nbins'].value) mod_heatmap = np.zeros(( self.options['nbins'].value+2, self.options['nbins'].value+2)) mod_heatmap[1:-1,1:-1] = heatmap.T #d_val = self.data[x_id] #if hasattr(self.data[x_id].flatten(), 'codes'): # d_val = self.data[x_id].flatten().codes traces = [] trace = { 'type': "contour", 'colorscale':[[0, 'rgb(255,255,255)'], [1, 'rgb(0,0,0)']],'showlegend':False, 'autocontour':False,'ncontours':self.options['ncontours'].value, 'contours':{'coloring':'heatmap'}, 'x0': xedges[0]-(xedges[1]-xedges[0])/2, 'dx': xedges[1]-xedges[0], 'y0': yedges[0]-(yedges[1]-yedges[0])/2, 'dy': yedges[1]-yedges[0], 'z':mod_heatmap } if self.only_subsets == False: traces.append(trace) trace = { 'type': "scattergl", 'mode': "markers", 'name': self.data.label, 'marker': dict({ 'symbol':'circle', 'size': self.options['marker_size'].value, 'color': 'rgba(0, 0, 0, 0.4)', 'line' : { 'width' : self.options['line_width'].value, 'color' : 'rgba(0, 0, 0, 0.3)' } }), 'x': self.data[x_id].flatten(), 'y': self.data[y_id].flatten(), } if self.only_subsets == False: traces.append(trace) for sset in self.data.subsets: color = sset.style.color trace = { 'type': "scattergl", 'mode': "markers", 'name': sset.label, 'marker': dict({ 'symbol':'circle', 'size': self.options['marker_size'].value, 'color': color, 'line' : { 'width' : self.options['line_width'].value, 'color' : '#000000'} }), 'selected':{'marker':{'color':color, 'size': self.options['marker_size'].value}}, 'unselected':{'marker':{'color':color, 'size': self.options['marker_size'].value}}, 'x': sset[x_id].flatten(), 'y': sset[y_id].flatten(), } traces.append(trace) layout = { 'title' : self.options['title'].value, 'margin' : {'l':50,'r':0,'b':50,'t':30 }, 'xaxis': { 'autorange' : True, 'zeroline': True, 'title' : self.options['xaxis'].value, 'type' : self.options['xscale'].value }, 'yaxis': { 'autorange':True, 'zeroline': True, 'title' : self.options['yaxis'].value, 'type' : self.options['yscale'].value }, 'showlegend': True, } return FigureWidget({ 'data': traces, 'layout': layout })
def createFigureWidget(self): x_id = self.dimensions[0] y_id_list = [ self.dimensions[i] for i in range(1, len(self.dimensions)) ] d_val = self.data[x_id] if hasattr(self.data[x_id], 'codes'): d_val = self.data[x_id].codes.flatten() hist, bin_edges = np.histogram(d_val.flatten(), bins='auto') bin_list = bin_edges.searchsorted(d_val.flatten(), 'right') xedges = [] for i in range(len(bin_edges) - 1): xedges.append((bin_edges[i + 1] + bin_edges[i]) / 2) traces = [] alpha_min, alpha_max, alpha_delta = self.getDeltaFunction( len(y_id_list), 0.1, 0.5) alpha_val = alpha_max for y_id in y_id_list: d_val = self.data[y_id] if hasattr(self.data[y_id], 'codes'): d_val = self.data[y_id].codes y_mean = [] y_std_u = [] y_std_l = [] y_min = [] y_max = [] for i in range(1, len(bin_edges)): d_col = d_val[(bin_list == i)].flatten() if len(d_col) > 0: i_mean = d_col.mean() i_min = d_col.min() i_max = d_col.max() i_std = d_col.std() else: i_mean = 0 i_std = 0 i_min = 0 i_max = 0 y_mean.append(i_mean) y_std_u.append(i_mean + i_std) y_std_l.append(i_mean - i_std) y_min.append(i_min) y_max.append(i_max) color = "#444444" color = 'rgba' + str(self.getDeltaColor(color, alpha_val)) trace = { 'type': "scatter", 'name': '-', 'marker': { 'color': color }, 'line': { 'width': 0 }, 'x': xedges, 'y': y_min, 'mode': 'lines', 'showlegend': False } if self.only_subsets == False: traces.append(trace) trace = { 'type': "scatter", 'name': self.data.label + "_" + y_id, 'marker': { 'color': color }, 'fillcolor': color, 'fill': 'tonexty', 'line': { 'color': color }, 'x': xedges, 'y': y_mean, 'mode': 'lines', } if self.only_subsets == False: traces.append(trace) trace = { 'type': "scatter", 'name': '+', 'marker': { 'color': color }, 'fillcolor': color, 'fill': 'tonexty', 'line': { 'width': 0 }, 'x': xedges, 'y': y_max, 'mode': 'lines', 'showlegend': False } if self.only_subsets == False: traces.append(trace) alpha_val = alpha_val - alpha_delta for sset in self.data.subsets: s_val = sset[x_id] if hasattr(sset[x_id], 'codes'): s_val = sset[x_id].codes bin_list = bin_edges.searchsorted(s_val, 'right') alpha_val = alpha_max for y_id in y_id_list: s_val = sset[y_id] if hasattr(sset[y_id], 'codes'): s_val = sset[y_id].codes y_s_mean = [] y_s_std_u = [] y_s_std_l = [] for i in range(1, len(bin_edges)): s_col = s_val[(bin_list == i)] if len(s_col) > 0: i_mean = s_col.mean() i_std = s_col.std() i_min = s_col.min() i_max = s_col.max() else: i_mean = 0 i_std = 0 i_min = 0 i_max = 0 y_s_mean.append(i_mean) y_s_std_u.append(i_mean + i_std) y_s_std_l.append(i_mean - i_std) color = sset.style.color color = 'rgba' + str(self.getDeltaColor(color, alpha_val)) trace = { 'type': "scatter", 'name': '-', 'marker': { 'color': color }, 'line': { 'width': 0 }, 'x': xedges, 'y': y_s_std_l, 'mode': 'lines', 'showlegend': False } traces.append(trace) trace = { 'type': "scatter", 'name': sset.label + "_" + y_id, 'marker': { 'color': color }, 'fillcolor': color, 'fill': 'tonexty', 'line': { 'color': color }, 'x': xedges, 'y': y_s_mean, 'mode': 'lines', } traces.append(trace) trace = { 'type': "scatter", 'name': '+', 'marker': { 'color': color }, 'fillcolor': color, 'fill': 'tonexty', 'line': { 'width': 0 }, 'x': xedges, 'y': y_s_std_u, 'mode': 'lines', 'showlegend': False } traces.append(trace) alpha_val = alpha_val - alpha_delta layout = { 'title': self.options['title'].value, 'margin': { 'l': 50, 'r': 0, 'b': 50, 't': 30 }, 'xaxis': { 'autorange': True, 'zeroline': True, 'title': self.options['xaxis'].value, }, 'yaxis': { 'autorange': True, 'zeroline': True, 'title': self.options['yaxis'].value, }, 'showlegend': True, 'barmode': 'overlay', } return FigureWidget({'data': traces, 'layout': layout})