def plot_page(df, columns, request, page): """Render the Bokeh plot. Inputs ------ df : pd.DataFrame The DataFrame with the data columns : list Which columns to use for choices in the plot request : flask The request object from flask page : str ('plot', 'plot_exo') Which page to render (for combined ['plot_exo'] or just SWEET-Cat ['plot']) Output ------ The rendered page with the plot """ colorscheme = 'Plasma' if request.method == 'POST': # Something is being submitted color = request.form['color'] x = str(request.form['x']) y = str(request.form['y']) z = str(request.form['z']) z = None if z == 'None' else z if (x not in columns) or (y not in columns): return redirect(url_for(page)) if (z is not None) and (z not in columns): return redirect(url_for(page)) colorscheme = str(request.form.get('colorscheme', colorscheme)) if colorscheme not in colorschemes.keys(): return redirect(url_for(page)) checkboxes = request.form.getlist("checkboxes") if not checkboxes: # When [] is returned checkboxes = [''] if checkboxes[0] not in [[], '', 'h**o']: return redirect(url_for(page)) df, x, y, z = extract(df, x, y, z, checkboxes) # Setting the limits x1, x2, y1, y2 = get_limits(request.form, x, y) if x.name != session.get('x', None): x1 = min(x) x2 = max(x) session['x'] = x.name if y.name != session.get('y', None): y1 = min(y) y2 = max(y) session['y'] = y.name xscale = str(request.form['xscale']) yscale = str(request.form['yscale']) if xscale not in ['linear', 'log']: return redirect(url_for(page)) if yscale not in ['linear', 'log']: return redirect(url_for(page)) else: if page == "plot_exo": x = 'discovered' y = 'plMass' z = None x1, x2 = 1985, 2020 y1, y2 = 0.0001, 200 session['x'] = 'discovered' session['y'] = 'plMass' session['z'] = 'None' else: x = 'teff' y = 'lum' z = 'logg' x1, x2 = 8000, 2500 y1, y2 = 1e-3, 3000 session['x'] = 'teff' session['y'] = 'lum' session['z'] = 'logg' yscale = 'log' color = 'Orange' xscale = 'linear' checkboxes = [] df, x, y, z = extract(df, x, y, z, checkboxes) # Check scale xscale, yscale, error = check_scale(x, y, xscale, yscale) stars = df['Star'] stars = list(stars.values) # Turn series into list. hover = HoverTool(tooltips=[ ("{}".format(x.name), "$x"), ("{}".format(y.name), "$y"), ("Star", "@star"), ]) num_points = count(x, y, [x1, x2], [y1, y2]) title = '{} vs. {}:\tNumber of objects in plot: {}'.format( x.name, y.name, num_points) tools = "crosshair,pan,wheel_zoom,box_zoom,reset,box_select,lasso_select,save".split( ',') fig = figure(title=title, tools=tools + [hover], plot_width=800, plot_height=400, toolbar_location='above', x_range=[x1, x2], y_range=[y1, y2], x_axis_type=xscale, y_axis_type=yscale) if z is not None: # Add colours and a colorbar COLORS, pallete = colorschemes[colorscheme] groups = pd.qcut(z.values, len(COLORS), duplicates="drop") c = [COLORS[xx] for xx in groups.codes] source = ColumnDataSource(data=dict(x=x, y=y, c=c, star=stars)) color_mapper = LinearColorMapper(palette=pallete, low=z.min(), high=z.max()) color_bar = ColorBar(color_mapper=color_mapper, label_standoff=12, border_line_color=None, location=(0, 0)) fig.add_layout(color_bar, 'right') fig.circle('x', 'y', source=source, size=10, color='c', fill_alpha=0.2, line_color=None) z = z.name fig.xaxis.axis_label = x.name fig.yaxis.axis_label = y.name color_bar.title = z else: # Simple colorbar source = ColumnDataSource(data=dict(x=x, y=y, star=stars)) fig.circle('x', 'y', source=source, size=10, color=colors[color], fill_alpha=0.2, line_color=None) fig.xaxis.axis_label = x.name fig.yaxis.axis_label = y.name # Horizontal histogram hhist, hedges, hmax = scaled_histogram(x, num_points, xscale) ph = figure(toolbar_location=None, plot_width=fig.plot_width, plot_height=200, x_range=fig.x_range, y_range=(-hmax * 0.1, hmax), min_border=10, min_border_left=50, y_axis_location="right", x_axis_type=xscale) ph.xgrid.grid_line_color = None ph.yaxis.major_label_orientation = np.pi / 4 ph.background_fill_color = "#fafafa" ph.quad(bottom=0, left=hedges[:-1], right=hedges[1:], top=hhist, color="white", line_color=colors[color]) # Vertical histogram vhist, vedges, vmax = scaled_histogram(y, num_points, yscale) pv = figure(toolbar_location=None, plot_width=200, plot_height=fig.plot_height, x_range=(-vmax * 0.1, vmax), y_range=fig.y_range, min_border=10, y_axis_location="right", y_axis_type=yscale) pv.ygrid.grid_line_color = None pv.xaxis.major_label_orientation = np.pi / 4 pv.background_fill_color = "#fafafa" pv.quad(left=0, bottom=vedges[:-1], top=vedges[1:], right=vhist, color="white", line_color=colors[color]) layout = column(row(fig, pv), row(ph, Spacer(width=200, height=200))) js_resources = INLINE.render_js() css_resources = INLINE.render_css() script, div = components(layout) if error is not None: flash('Scale was changed from log to linear') html = render_template('plot.html', plot_script=script, plot_div=div, js_resources=js_resources, css_resources=css_resources, color=color, colors=colors, x=x.name, y=y.name, z=z, x1=x1, x2=x2, y1=y1, y2=y2, xscale=xscale, yscale=yscale, checkboxes=checkboxes, columns=columns, colorschemes=colorschemes, colorscheme=colorscheme) return encode_utf8(html)
p.title.text_font_size = "25px" p.xaxis.axis_label = 'dBZ' p.yaxis.axis_label = 'Height(km)' color_mapper = LogColorMapper(palette="Spectral11", low=1, \ high=max(bins.counts)) from bokeh.transform import linear_cmap, log_cmap linearc=log_cmap('counts', 'Spectral11', 1, max(bins.counts)) p.hex_tile(q="q", r="r", size=0.5, line_color=None, source=bins, fill_color=linearc) color_mapper = LogColorMapper(palette="Spectral11", low=1, high=max(bins.counts)) color_bar = ColorBar(color_mapper=color_mapper, ticker=LogTicker(), label_standoff=12, border_line_color=None, location=(0,0)) color_bar.major_label_text_font_size="20pt" color_bar.title="Counts" color_bar.title_text_font_size="20pt" p.add_layout(color_bar, 'right') bokeh.io.export_png(p, filename="cfadKa_att.png") bokeh.io.output_file("hex_tile.html") bokeh.io.show(p) bins2 = bokeh.util.hex.hexbin( z3dm[:,:,:,0].T.flatten(),\ h[1:,:,nx1:nx2].flatten(),\ 0.5) from bokeh.models import Range1d, LogColorMapper, LogTicker, ColorBar
def add_colorbar(figure, colormap=None, low=0, high=1, unit=None, clabel=None, colorbar_figure=None): if colormap is None: color_map = "Viridis256" elif isinstance(colormap, str): if colormap.lower() in ( "greys", "inferno", "magma", "plasma", "viridis", "cividis", "turbo", ): color_map = colormap[0].upper() + colormap[1:].lower() + "256" else: color_map = mpl.cm.get_cmap(colormap) color_map = [ "#%02x%02x%02x" % (int(r), int(g), int(b)) for r, g, b, _ in 255 * color_map(np.linspace(0, 1, 256)) ] else: color_map = colormap try: color_map = LinearColorMapper(palette=color_map, low=low, high=high, name="color_mapper") except ValueError as e: try: import colorcet except ImportError: raise ValueError( "colormap not found; try installing the colorcet package" ) from e else: raise color_bar = ColorBar( color_mapper=color_map, ticker=BasicTicker(name="ticker"), border_line_color=None, margin=0, name="color_bar", ) color_bar.background_fill_color = None # glyph_renderers.append(color_bar) if unit is None: unit = clabel if colorbar_figure is None: if unit is not None: color_bar.title = unit figure.add_layout(color_bar, place="right") else: if unit is not None: colorbar_figure.title.text = unit colorbar_figure.title_location = "right" colorbar_figure.title.align = "center" color_bar.height = colorbar_figure.plot_height if isinstance(colorbar_figure.center[-1], ColorBar): colorbar_figure.center = colorbar_figure.center[:-1] colorbar_figure.add_layout(color_bar, place="center")
def scalar_map_2d(cells, values, clim=None, figure=None, delaunay=False, colorbar=True, colormap=None, unit=None, clabel=None, colorbar_figure=None, xlim=None, ylim=None, **kwargs): """ Plot an interactive 2D scalar map as a colourful image. Arguments: cells (Partition): spatial description of the cells values (pandas.Series or pandas.DataFrame): feature value at each cell/bin, encoded into a colour clim (2-element sequence): passed to :func:`~matplotlib.cm.ScalarMappable.set_clim` figure (bokeh.plotting.figure.Figure): figure handle delaunay (bool or dict): overlay the Delaunay graph; if ``dict``, options are passed to :func:`~tramway.plot.bokeh.plot_delaunay` colorbar (bool or str or dict): add a colour bar; if ``dict``, options are passed to :func:`~bokeh.models.ColorBar` unit/clabel (str): colorbar label, usually the unit of displayed feature colormap (str): colormap name; see also https://matplotlib.org/users/colormaps.html xlim (2-element sequence): lower and upper x-axis bounds ylim (2-element sequence): lower and upper y-axis bounds """ if isinstance(values, pd.DataFrame): feature_name = values.columns[0] values = values.iloc[:,0] # to Series else: feature_name = None if figure is None: assert False figure = plt.figure() polygons = [] xy = cells.tessellation.cell_centers if not xlim or not ylim: xy_min, _, xy_max, _ = mplt._bounding_box(cells, xy) if not xlim: xlim = (xy_min[0], xy_max[0]) if not ylim: ylim = (xy_min[1], xy_max[1]) ix = np.arange(xy.shape[0]) vertices, cell_vertices, Av = mplt.box_voronoi_2d(cells.tessellation, xlim, ylim) try: ok = 0 < cells.location_count except (KeyboardInterrupt, SystemExit): raise except: print(traceback.format_exc()) ok = np.ones(ix.size, dtype=bool) if cells.tessellation.cell_label is not None: ok = np.logical_and(ok, 0 < cells.tessellation.cell_label) map_defined = np.zeros_like(ok) map_defined[values.index] = True ok[np.logical_not(map_defined)] = False ok[ok] = np.logical_not(np.isnan(values.loc[ix[ok]].values)) for i in ix[ok]: vs = cell_vertices[i].tolist() # order the vertices so that they draw a polygon v0 = v = vs[0] vs = set(vs) _vertices = [] #vvs = [] # debug while True: _vertices.append(vertices[v]) #vvs.append(v) vs.remove(v) if not vs: break ws = set(Av.indices[Av.indptr[v]:Av.indptr[v+1]]) & vs if not ws: ws = set(Av.indices[Av.indptr[v0]:Av.indptr[v0+1]]) & vs if ws: _vertices = _vertices[::-1] else: #print((v, vs, vvs, [Av.indices[Av.indptr[v]:Av.indptr[v+1]] for v in vs])) warn('cannot find a path that connects all the vertices of a cell', RuntimeWarning) break v = ws.pop() # if _vertices: _vertices = np.vstack(_vertices) polygons.append((_vertices[:,0], _vertices[:,1])) scalar_map = values.loc[ix[ok]].values vmin, vmax = scalar_map.min(), scalar_map.max() clim = {} if clim is None else dict(vmin=clim[0], vmax=clim[1]) scalar_map = mpl.colors.Normalize(**clim)(scalar_map) if colormap: color_map = mpl.cm.get_cmap(colormap) else: color_map = mpl.cm.viridis colors = [ "#%02x%02x%02x" % (int(r), int(g), int(b)) for r, g, b, _ in 255*color_map(scalar_map) ] patch_kwargs = dict(fill_color=colors, line_width=0) figure.patches(*zip(*polygons), **patch_kwargs) if delaunay or isinstance(delaunay, dict): if not isinstance(delaunay, dict): delaunay = {} plot_delaunay(cells, figure=figure, **delaunay) figure.x_range = Range1d(*xlim) figure.y_range = Range1d(*ylim) if colorbar: low = clim.get('vmin', vmin) high = clim.get('vmax', vmax) color_map = 'Viridis256' if colormap is None else colormap color_map = LinearColorMapper(palette=color_map, low=low, high=high) color_bar = ColorBar(color_mapper=color_map, ticker=BasicTicker(), border_line_color=None, margin=0) color_bar.background_fill_color = None if unit is None: unit = clabel if colorbar_figure is None: if unit is not None: color_bar.title = unit figure.add_layout(color_bar, place='right') else: if unit is not None: colorbar_figure.title.text = unit colorbar_figure.title_location = 'right' colorbar_figure.title.align = 'center' color_bar.height = colorbar_figure.plot_height if isinstance(colorbar_figure.center[-1], ColorBar): colorbar_figure.center = colorbar_figure.center[:-1] colorbar_figure.add_layout(color_bar, place='center')