def create_plot(): """Creates scatter plot. Note: While it is usually enough to update the data source, redrawing the plot is needed for bond_type coloring, when the colormap needs to change and the colorbar is removed. """ global source p_new = figure( plot_height=600, plot_width=700, toolbar_location='above', tools=[ 'pan', 'wheel_zoom', 'box_zoom', 'save', 'reset', hover, tap, ], #active_scroll='box_zoom', active_drag='box_zoom', output_backend='webgl', title='', title_location='right', lod_threshold=50, lod_factor=100, ) p_new.title.align = 'center' p_new.title.text_font_size = '10pt' p_new.title.text_font_style = 'italic' if inp_clr.value == 'bond_type': from bokeh.transform import factor_cmap paper_palette = list(config.bondtype_dict.values()) fill_color = factor_cmap('color', palette=paper_palette, factors=bondtypes) p_new.circle('x', 'y', size=10, source=source, fill_color=fill_color, fill_alpha=0.6, line_alpha=0.4, legend='color') else: cmap = bmd.LinearColorMapper(palette=Viridis256) fill_color = {'field': 'color', 'transform': cmap} p_new.circle('x', 'y', size=10, source=source, fill_color=fill_color) cbar = bmd.ColorBar(color_mapper=cmap, location=(0, 0)) #cbar.color_mapper = bmd.LinearColorMapper(palette=Viridis256) p_new.add_layout(cbar, 'right') return p_new
def create_plot(): """Creates scatter plot. Note: While it is usually enough to update the data source, redrawing the plot is needed for bond_type coloring, when the colormap needs to change and the colorbar is removed. """ global source p_new = figure( plot_height=600, plot_width=700, toolbar_location="above", tools=["pan", "wheel_zoom", "box_zoom", "save", "reset", hover, tap], # active_scroll='box_zoom', active_drag="box_zoom", output_backend="webgl", title="", title_location="right", ) p_new.title.align = "center" p_new.title.text_font_size = "10pt" p_new.title.text_font_style = "italic" if inp_clr.value == "group": from bokeh.transform import factor_cmap paper_palette = list(config.group_dict.values()) sample_palette = list(config.sampled_dict.values()) fill_color = factor_cmap("color", palette=paper_palette, factors=groups) line_color = factor_cmap("color", palette=sample_palette, factors=["sampled", "not sampled"]) p_new.circle( "x", "y", size="sampled", line_width="lw", line_alpha=0.5, line_color=line_color, source=source, fill_color=fill_color, # fill_alpha=0.6, legend="color", ) else: cmap = bmd.LinearColorMapper(palette=Viridis256) fill_color = {"field": "color", "transform": cmap} p_new.circle("x", "y", size=10, source=source, fill_color=fill_color) cbar = bmd.ColorBar(color_mapper=cmap, location=(0, 0)) # cbar.color_mapper = bmd.LinearColorMapper(palette=Viridis256) p_new.add_layout(cbar, "right") return p_new
def get_map(self): import bokeh.plotting as bplt import bokeh.models as bm wheel_zoom = bm.WheelZoomTool() self.hover = bm.HoverTool(tooltips=[ ("Navn", "@kommuner"), #("(Long, Lat)", "($x, $y)"), ("Dato", "@kommuner_dates"), ("stemme pct", "@stemme_pct %"), ]) self.hover.point_policy = "follow_mouse" tools = [ bm.PanTool(), bm.BoxZoomTool(), wheel_zoom, bm.SaveTool(), bm.ResetTool(), bm.UndoTool(), bm.RedoTool(), bm.CrosshairTool(), self.hover ] fig = bplt.figure(title="Test", tools=tools, x_axis_location=None, y_axis_location=None, match_aspect=True) # Activate scrool fig.toolbar.active_scroll = wheel_zoom # Remove grid lines fig.grid.grid_line_color = None # Check if source exists if not hasattr(self, 'source'): self.make_map_source() # Make color mapper #from bokeh.palettes import Viridis6 as palette #from bokeh.palettes import Spectral11 as palette from bokeh.palettes import RdYlGn11 as palette palette.reverse() #color_mapper = bm.LogColorMapper(palette=palette, high=90., low=50.) color_mapper = bm.LinearColorMapper(palette=palette, high=90., low=50.) # Plot fig.patches(xs='x_lon', ys='y_lat', source=self.source, fill_color={ 'field': 'stemme_pct', 'transform': color_mapper }, fill_alpha=0.7, line_color="white", line_width=0.5) return fig
def add_numerical_colormap(self, palette, numeric_name, nan_color='gray', colorbar=True, cb_orientation='vertical', cb_location='right', label_standoff=12, border_line_color=None, location=(0,0), **kwargs): """ Create a Numerical Colormap. Parameters ---------- palette: str or Tuple The color palette of the colormap. It can either be one of Bokeh's default palettes or a Tuple of colors in hexadecimal format. numeric_name: str The column name of the loaded dataset that contains the numerical values nan_color: str or bokeh.colors instance (default: ```'gray'```) The color name for the geometries that are outside the range of the colormap colorbar: boolean (default: True) Draw a colorbar alongside the Canvas cb_orientation: str (either ```'vertical'```, ```'horizontal'```) The orientation of the colorbar cb_location: str (either ```'left'```, ```'right'```, ```'above'```, ```'below'```) The location of the colorbar relative to the Canvas label_standoff: int (default: 12) The distance (in pixels) to separate the tick labels from the color bar. border_line_color: str or bokeh.colors instance (default: None) The color of the border of the colorbar location: Tuple (int, int) Adjust the colorbar location relative to ```cb_orientation``` and ```cb_location``` **kwargs: Dict Other aarguments related to the creation of the colorbar Returns ------- cmap: Dict The Numerical Colormap """ if palette not in ALLOWED_NUMERICAL_COLOR_PALETTES: raise ValueError(f'Invalid Palette Name. Allowed (pre-built) Palettes: {ALLOWED_NUMERICAL_COLOR_PALETTES}') min_val, max_val = self.data[numeric_name].agg([np.min, np.max]) cmap = bokeh_mdl.LinearColorMapper(palette=getattr(palettes, palette), low=min_val, high=max_val, nan_color=nan_color) if colorbar: cbar = bokeh_mdl.ColorBar(orientation=cb_orientation, color_mapper=cmap, label_standoff=label_standoff, border_line_color=border_line_color, location=location, **kwargs) # Other Params: height=height, width=width self.figure.add_layout(cbar, cb_location) # self.cmap = {'type':'add_numerical_colormap', 'cmap':{'field': numeric_name, 'transform': cmap}} self.cmap = {'field': numeric_name, 'transform': cmap} return self.cmap
def plot_slopes(x_corpus: VectorizedCorpus, most_deviating: pd.DataFrame, metric: str, plot_height: int = 300, plot_width: int = 300) -> Dict: data = generate_slopes(x_corpus, most_deviating, metric) source = bm.ColumnDataSource(data) color_mapper = bm.LinearColorMapper(palette='Magma256', low=min(data['k']), high=max(data['k'])) p: bp.Figure = bp.figure(plot_height=plot_height, plot_width=plot_width, tools='pan,wheel_zoom,box_zoom,reset') p.multi_line( xs='xs', ys='ys', line_width=1, line_color={ 'field': 'k', 'transform': color_mapper }, line_alpha=0.6, hover_line_alpha=1.0, source=source, ) # , legend="token" p.add_tools( bm.HoverTool( show_arrow=False, line_policy='next', tooltips=[('Token', '@token'), ('Slope', '@k{1.1111}')], # , ('P-value', '@p{1.1111}')] )) bp.show(p)
def image(img, x=None, y=None, colormap='Plasma256', clim=None, clabel=None, title=None, xlabel=None, ylabel=None, xlim=None, ylim=None, xtype='auto', ytype='auto', width=None, height=None, hold=False, interactive=None): """Plot a heatmap of 2D scalar data. :param img: 2D image data :param x: x-axis range for image data (min, max) :param y: y-axis range for image data (min, max) :param colormap: named color palette or Bokeh ColorMapper (see `Bokeh palettes <https://bokeh.pydata.org/en/latest/docs/reference/palettes.html>`_) :param clim: color axis limits (min, max) :param clabel: color axis label :param title: figure title :param xlabel: x-axis label :param ylabel: y-axis label :param xlim: x-axis limits (min, max) :param ylim: y-axis limits (min, max) :param xtype: x-axis type ('auto', 'linear', 'log', etc) :param ytype: y-axis type ('auto', 'linear', 'log', etc) :param width: figure width in pixels :param height: figure height in pixels :param interactive: enable interactive tools (pan, zoom, etc) for plot :param hold: if set to True, output is not plotted immediately, but combined with the next plot >>> import arlpy.plot >>> import numpy as np >>> arlpy.plot.image(np.random.normal(size=(100,100)), colormap='Inferno256') """ global _figure if x is None: x = (0, img.shape[1] - 1) if y is None: y = (0, img.shape[0] - 1) if xlim is None: xlim = x if ylim is None: ylim = y if _figure is None: _figure = _new_figure(title, width, height, xlabel, ylabel, xlim, ylim, xtype, ytype, interactive) if clim is None: clim = [_np.amin(img), _np.amax(img)] if not isinstance(colormap, _bmodels.ColorMapper): colormap = _bmodels.LinearColorMapper(palette=colormap, low=clim[0], high=clim[1]) _figure.image([img], x=x[0], y=y[0], dw=x[-1] - x[0], dh=y[-1] - y[0], color_mapper=colormap) cbar = _bmodels.ColorBar(color_mapper=colormap, location=(0, 0), title=clabel) _figure.add_layout(cbar, 'right') if not hold and not _hold: _show(_figure) _figure = None
def get_plot(inp_x, inp_y, inp_clr): """Returns a Bokeh plot of the input values, and a message with the number of COFs found.""" q_list = [quantities[label] for label in [inp_x, inp_y, inp_clr]] db_nodes_dict = get_db_nodes_dict( ) # TODO: try to move outside, to load it once! results = get_figure_values( db_nodes_dict, q_list) #returns [inp_x_value, inp_y_value, inp_clr_value, cif.label] # prepare data for plotting nresults = len(results) msg = "{} MOFs found.<br> <b>Click on any point for details!</b>".format( nresults) label, x, y, clrs = zip(*results) x = list(map(float, x)) y = list(map(float, y)) clrs = list(map(float, clrs)) mat_id = label data = {'x': x, 'y': y, 'color': clrs, 'mat_id': mat_id} # create bokeh plot source = bmd.ColumnDataSource(data=data) hover = bmd.HoverTool(tooltips=[]) tap = bmd.TapTool() p_new = bpl.figure( plot_height=600, plot_width=600, toolbar_location='above', tools=[ 'pan', 'wheel_zoom', 'box_zoom', 'save', 'reset', hover, tap, ], active_drag='box_zoom', output_backend='webgl', title='', # trick: title is used as the colorbar label title_location='right', x_axis_type=q_list[0]['scale'], y_axis_type=q_list[1]['scale'], ) p_new.title.align = 'center' p_new.title.text_font_size = '10pt' p_new.title.text_font_style = 'italic' update_legends(p_new, q_list, hover) tap.callback = bmd.OpenURL(url="detail_pyrenemofs?mat_id=@mat_id") cmap = bmd.LinearColorMapper(palette=Plasma256, low=min(clrs), high=max(clrs)) fill_color = {'field': 'color', 'transform': cmap} p_new.circle('x', 'y', size=10, source=source, fill_color=fill_color) cbar = bmd.ColorBar(color_mapper=cmap, location=(0, 0)) p_new.add_layout(cbar, 'right') return p_new, msg
def get_plot(appl): #pylint: disable=too-many-locals """Make the bokeh plot for a given application. 1. read important metrics from applications.yml 2. read metadata for thes metricy in quantities.yml 3. query the AiiDA database for values 4. rank materials according to their performance 5. generate the plot and return a message stating the number of found materials """ # Query for results q_list = tuple([quantities[label] for label in [appl['x'], appl['y']]]) results_wnone = get_data_aiida( q_list) #[[id_material, name_material, class_material, xval, yval]] # Clean the query from None values projections results = [] for l in results_wnone: if None not in l: results.append(l) # Prepare data for plotting nresults = len(results) if not results: results = [['none', 'none', 'none', 0, 0]] msg = "No materials found" else: msg = "{} materials shown".format(nresults) mat_id, name, class_mat, x, y = zip(*results) x = list(map(float, x)) y = list(map(float, y)) rank = rank_materials(x, y, appl['wx'], appl['wy']) # Setup plot hover = bmd.HoverTool() hover.tooltips = [ ("name", "@name"), ("MAT_ID", "@mat_id"), (q_list[0]["label"], "@x {}".format(q_list[0]["unit"])), (q_list[1]["label"], "@y {}".format(q_list[1]["unit"])), ('ranking', '@color'), ] tap = bmd.TapTool() p = bpl.figure( plot_height=600, plot_width=600, toolbar_location="right", # choose: above, below, right, left tools=[ 'pan', 'wheel_zoom', 'box_zoom', 'save', 'reset', hover, tap, ], active_drag='box_zoom', output_backend='webgl', x_axis_type=q_list[0]['scale'], y_axis_type=q_list[1]['scale'], x_axis_label="{} [{}]".format(q_list[0]["label"], q_list[0]["unit"]), y_axis_label="{} [{}]".format(q_list[1]["label"], q_list[1]["unit"]), ) tap.callback = bmd.OpenURL(url="details?mat_id=@mat_id") cmap = bmd.LinearColorMapper(palette=myRdYlGn) fill_color = {'field': 'color', 'transform': cmap} source = bmd.ColumnDataSource( data={ 'mat_id': mat_id, 'name': name, 'class_mat': class_mat, 'x': x, 'y': y, 'color': rank, }) p.circle(x='x', y='y', size=10, source=source, fill_color=fill_color, muted_alpha=0.2) #cbar = bmd.ColorBar(color_mapper=cmap, location=(0, 0)) #p.add_layout(cbar, 'right') #show colorbar return p, msg
fig = bplt.figure(title="Test", tools=tools, x_axis_location=None, y_axis_location=None, match_aspect=False) # Activate scrool fig.toolbar.active_scroll = wheel_zoom # Remove grid lines fig.grid.grid_line_color = None # from bokeh.palettes import RdYlGn11 as palette palette.reverse() #color_mapper = bm.LogColorMapper(palette=palette) color_mapper = bm.LinearColorMapper(palette=palette) fig.patches(xs='xs', ys='ys', source=gs, fill_color={ 'field': 'AREAL', 'transform': color_mapper }, fill_alpha=0.7, line_color="white", line_width=0.5) """# Show output""" # Get output. Either to Jupyter notebook or html file if True: if kommune.check_isnotebook():
def confusion_matrix(y_true, y_pred): plot_width, plot_height = 600, 500 # based on https://stackoverflow.com/questions/49135741/bokeh-heatmap-from-pandas-confusion-matrix labels = y_true.unique() cm = metrics.confusion_matrix( y_true, y_pred, labels=labels, normalize='true') * 100. df = pd.DataFrame(data=cm, columns=labels, index=labels) print(df) df.index.name = 'True' df.columns.name = 'Prediction' # Prepare data.frame in the right format df = df.stack().rename("value").reset_index() df['label'] = df['value'].apply(lambda x: "{:0.0f}".format(x)) source = mpl.ColumnDataSource(df) # You can use your own palette here colors = ['#d7191c', '#fdae61', '#ffffbf', '#a6d96a', '#1a9641'] # Had a specific mapper to map color with value mapper = mpl.LinearColorMapper(palette='Viridis256', low=df.value.min(), high=df.value.max()) # Define a figure p = bpl.figure( plot_width=plot_width, plot_height=plot_height, x_range=list(labels), y_range=list(labels), # toolbar_location=None, tools="", ) # Create rectangle for heatmap r = p.rect(x="Prediction", y="True", width=1, height=1, source=source, line_color=None, fill_color=transform('value', mapper)) p.xaxis.axis_label = 'Predicted values' p.yaxis.axis_label = 'True values' text_props = { "source": source, "text_align": "center", "text_baseline": "middle", "text_color": 'white' } p.text(x='Prediction', y="True", text="label", **text_props) p.add_tools( mpl.HoverTool(tooltips=[("value", "@value")], mode="mouse", point_policy="follow_mouse", renderers=[r])) # Add legend color_bar = mpl.ColorBar( color_mapper=mapper, location=(0, 0), ticker=mpl.BasicTicker(desired_num_ticks=len(colors))) p.add_layout(color_bar, 'right') return p
} for c_id, coord in coord_fixes.items(): cid = c_abr_to_id[c_id] world_region["x"].loc[cid] = coord[0] world_region["y"].loc[cid] = coord[1] if region_name: world_region = world_region.loc[world_region['continent'] == region_name] plot_df = bm.GeoJSONDataSource(geojson=world_region.to_json()) p = bp.figure(title=value_to_draw, x_range=(-22, 40), y_range=(35, 72)) map_palette = colorcet.bkr m = 20 color_mapper = bm.LinearColorMapper(palette=map_palette, low=-m, high=m) p.patches('xs', 'ys', fill_alpha=1.0, fill_color={ 'field': value_to_draw, 'transform': color_mapper }, line_color='black', line_width=1.0, source=plot_df) color_bar = bm.ColorBar(color_mapper=color_mapper, ticker=bm.LogTicker(), label_standoff=12, border_line_color=None,
def get_plot(inp_x, inp_y, inp_clr): """Returns a Bokeh plot of the input values, and a message with the number of COFs found.""" q_list = [config.quantities[label] for label in [inp_x, inp_y, inp_clr]] results_wnone = get_data_aiida(q_list) #returns *** # dump None lists that make bokeh crash results = [] for l in results_wnone: if None not in l: results.append(l) # prepare data for plotting nresults = len(results) if not results: results = [['x', 'x', 'x', 0, 0, 0]] msg = "No matching COFs found." else: msg = "{} COFs found.<br> <b>Click on any point for details!</b>".format(nresults) mat_id, mat_name, mat_class, x, y, clrs = zip(*results) # returned *** x = list(map(float, x)) y = list(map(float, y)) clrs = list(map(float, clrs)) data = {'x': x, 'y': y, 'color': clrs, 'mat_id': mat_id, 'mat_name': mat_name, 'mat_class': mat_class} # create bokeh plot source = bmd.ColumnDataSource(data=data) hover = bmd.HoverTool(tooltips=[]) tap = bmd.TapTool() p_new = bpl.figure( plot_height=600, plot_width=600, toolbar_location='above', tools=[ 'pan', 'wheel_zoom', 'box_zoom', 'save', 'reset', hover, tap, ], active_drag='box_zoom', output_backend='webgl', title='', # trick: title is used as the colorbar label title_location='right', x_axis_type=q_list[0]['scale'], y_axis_type=q_list[1]['scale'], ) p_new.title.align = 'center' p_new.title.text_font_size = '10pt' p_new.title.text_font_style = 'italic' update_legends(p_new, q_list, hover) tap.callback = bmd.OpenURL(url="detail?mat_id=@mat_id") # Plot vertical line for comparison with amine-based technology (PE=1MJ/kg) if inp_y == 'CO2 parasitic energy (coal)': hline = bmd.Span(location=1, dimension='width', line_dash='dashed', line_color='grey', line_width=3) p_new.add_layout(hline) hline_descr = bmd.Label(x=30, y=1, x_units='screen', text_color='grey', text='amine-based sep.') p_new.add_layout(hline_descr) cmap = bmd.LinearColorMapper(palette=Plasma256, low=min(clrs), high=max(clrs)) fill_color = {'field': 'color', 'transform': cmap} p_new.circle('x', 'y', size=10, source=source, fill_color=fill_color) cbar = bmd.ColorBar(color_mapper=cmap, location=(0, 0)) p_new.add_layout(cbar, 'right') return p_new, msg
def blot(gdata, args=(), figure=None, squeeze=False, streamline=False, quiver=False, contour=False, diverging=False, group=None, xscale=1.0, yscale=1.0, style=None, legend=True, labelPrefix='', xlabel=None, ylabel=None, title=None, logx=False, logy=False, logz=False, color=None, fixaspect=False, vmin=None, vmax=None, edgecolors=None, **kwargs): """Plots Gkeyll data Unifies the plotting across a wide range of Gkyl applications. Can be used for both 1D an 2D data. Uses a proper colormap by default. Args: """ #----------------------------------------------------------------- #-- Data Loading ------------------------------------------------- numDims = gdata.getNumDims(squeeze=True) if numDims > 2: raise Exception('Only 1D and 2D plots are currently supported') #end # Get the handles on the grid and values grid = gdata.getGrid() values = gdata.getValues() lower, upper = gdata.getBounds() cells = gdata.getNumCells() # Squeeze the data (get rid of "collapsed" dimensions) axLabel = ['z_0', 'z_1', 'z_2', 'z_3', 'z_4', 'z_5'] if len(grid) > numDims: idx = [] for d in range(len(grid)): if cells[d] <= 1: idx.append(d) #end #end if idx: grid = np.delete(grid, idx) lower = np.delete(lower, idx) upper = np.delete(upper, idx) cells = np.delete(cells, idx) axLabel = np.delete(axLabel, idx) values = np.squeeze(values, tuple(idx)) #end numComps = values.shape[-1] if streamline or quiver: step = 2 else: step = 1 #end idxComps = range(int(np.floor(numComps / step))) numComps = len(idxComps) if xscale != 1.0: axLabel[0] = axLabel[0] + r' $\times$ {:.3e}'.format(xscale) #end if numDims == 2 and yscale != 1.0: axLabel[1] = axLabel[1] + r' $\times$ {:.3e}'.format(yscale) #end sr = np.sqrt(numComps) #determine the number of rows and columns if sr == np.ceil(sr): numRows = int(sr) numCols = int(sr) elif np.ceil(sr) * np.floor(sr) >= numComps: numRows = int(np.floor(sr)) numCols = int(np.ceil(sr)) else: numRows = int(np.ceil(sr)) numCols = int(np.ceil(sr)) # Prepare the figure if figure is None: fig = [] if numDims == 1: tooltips = [(axLabel[0], "$x"), ("value", "$y") ] #getting tooltips ready for different dimensions else: if streamline or quiver: tooltips = None else: tooltips = [(axLabel[0], "$x"), (axLabel[1], "$y"), ("value", "@image")] #end #end for comp in idxComps: if logx and logy: fig.append( blt.figure(tooltips=tooltips, x_axis_type="log", y_axis_type="log", frame_height=int(600.0 / numRows), frame_width=int(600.0 / numRows), outline_line_color='black', min_border_left=70, min_border_right=50, min_border_bottom=10)) elif logx: fig.append( blt.figure( tooltips=tooltips, x_axis_type="log", frame_height=int( 600.0 / numRows ), #adjust figures with the size based on the screen size frame_width=int(600.0 / numRows), outline_line_color='black', min_border_left=70, min_border_right=50, min_border_bottom=10) ) #adjust spacings betweewn subplots to be aligned elif logy: fig.append( blt.figure(tooltips=tooltips, y_axis_type="log", frame_height=int(600.0 / numRows), frame_width=int(600.0 / numRows), outline_line_color='black', min_border_left=70, min_border_right=50, min_border_bottom=10)) else: fig.append( blt.figure(tooltips=tooltips, frame_height=int(600.0 / numRows), frame_width=int(600.0 / numRows), outline_line_color='black', min_border_left=70, min_border_right=60, min_border_bottom=10)) #-- Preparing the Axes ------------------------------------------- for comp in idxComps: fig[comp].xaxis.minor_tick_line_color = None #deleting minor ticks fig[comp].yaxis.minor_tick_line_color = None fig[comp].xaxis.major_label_text_font_size = '12pt' #tick font size adjustment fig[comp].yaxis.major_label_text_font_size = '12pt' fig[comp].xaxis.axis_label_text_font_size = '12pt' #label font size adjustment fig[comp].yaxis.axis_label_text_font_size = '12pt' fig[comp].xaxis.formatter = bm.BasicTickFormatter( precision=1) #adjust floating numbers of ticks fig[comp].yaxis.formatter = bm.BasicTickFormatter(precision=1) if numDims != 1: if comp % numCols != 0: #hiding labels for unnecessary locations fig[comp].yaxis.major_label_text_font_size = '0pt' #end if comp < (numRows - 1) * numCols: fig[comp].xaxis.major_label_text_font_size = '0pt' #end #end if comp >= (numRows - 1) * numCols: if xlabel is None: fig[comp].xaxis.axis_label = axLabel[0] else: #if there is xlabel to be specified fig[comp].xaxis.axis_label = xlabel #end #end #end if comp % numCols == 0: if ylabel is None: if numDims == 2: fig[comp].yaxis.axis_label = axLabel[1] #end else: fig[comp].yaxis.axis_label = ylabel #end #end #end #-- Main Plotting Loop ------------------------------------------- for comp in idxComps: if len(idxComps) > 1: if labelPrefix == "": label = str(comp) else: label = '{:s}_c{:d}'.format(labelPrefix, comp) #end else: label = labelPrefix #end #end # Special plots if numDims == 1: x = 0.5 * (grid[0][1:] + grid[0][:-1]) fig[comp].line(x, values[..., comp], line_width=2, legend=label) elif numDims == 2: if contour: pass elif streamline: magnitude = np.sqrt(values[..., 2 * comp]**2 + values[..., 2 * comp + 1]**2) gridCC = _gridNodalToCellCentered(grid, cells) plt.subplots(numRows, numCols, sharex=True, sharey=True) strm = plt.streamplot( gridCC[0] * xscale, gridCC[1] * yscale, # make streamline plot by matplotlib first values[..., 2 * comp].transpose(), values[..., 2 * comp + 1].transpose(), color=magnitude.transpose(), linewidth=2) lines = strm.lines # get the line and color data of matplotlib streamline pathes = lines.get_paths() arr = lines.get_array().data points = np.stack([p.vertices.T for p in pathes], axis=0) X = points[:, 0, :].tolist() Y = points[:, 1, :].tolist() mapper = bt.linear_cmap(field_name="color", palette=bp.Inferno256, low=arr.min(), high=arr.max()) # use the data to create a multiline, use linear_map and palette to set the color of the lines: source = bm.ColumnDataSource(dict(x=X, y=Y, color=arr)) fig[comp].multi_line("x", "y", line_color=mapper, source=source, line_width=3) colormapper = bm.LinearColorMapper( palette='Inferno256', low=np.amin(magnitude.transpose()), high=np.amax(magnitude.transpose())) #adding a color bar color_bar = bm.ColorBar( color_mapper=colormapper, width=7, location=(0, 0), formatter=bm.BasicTickFormatter( precision=1), #deleting unnecessary floating numbers ticker=bm.BasicTicker(desired_num_ticks=4), label_standoff=13, major_label_text_font_size='12pt', border_line_color=None, padding=2, bar_line_color='black') fig[comp].add_layout(color_bar, 'right') elif quiver: gridCC = _gridNodalToCellCentered(grid, cells) x_range = gridCC[0] * xscale #setting x coordinates y_range = gridCC[1] * yscale #setting y coordinates dx = grid[0][1] - grid[0][0] dy = grid[1][1] - grid[1][0] freq = 7 v_x = values[..., 2 * comp].transpose() v_y = values[..., 2 * comp + 1].transpose() X, Y = np.meshgrid(x_range, y_range) speed = np.sqrt(v_x**2 + v_y**2) theta = np.arctan2(v_y * dy, v_x * dx) #arctan(y/x) maxSpeed = speed.max() x0 = X[::freq, ::freq].flatten() y0 = Y[::freq, ::freq].flatten() length = speed[::freq, ::freq].flatten() / maxSpeed angle = theta[::freq, ::freq].flatten() x1 = x0 + 0.9 * freq * dx * v_x[::freq, ::freq].flatten( ) / speed[::freq, ::freq].max() y1 = y0 + 0.9 * freq * dy * v_y[::freq, ::freq].flatten( ) / speed[::freq, ::freq].max() fig[comp].segment(x0, y0, x1, y1, color='black') #vector line fig[comp].triangle(x1, y1, size=4.0, angle=angle - np.pi / 2, color='black') #vector arrow elif diverging: gridCC = _gridNodalToCellCentered(grid, cells) vmax = np.abs(values[..., comp]).max() x_range = grid[0] * xscale #setting x coordinates y_range = grid[1] * yscale #setting y coordinates CmToRgb = (255 * cm.RdBu_r(range(256))).astype( 'int') #extract colors from maplotlib colormap RgbToHexa = [ bc.RGB(*tuple(rgb)).to_hex() for rgb in CmToRgb ] # convert RGB numbers into colormap hexacode string mapper = bm.LinearColorMapper(palette=RgbToHexa, low=-vmax, high=vmax) #adding a color bar fig[comp].image(image=[values[..., comp].transpose()], x=x_range[0], y=y_range[0], dw=(x_range[-1] - x_range[0]), dh=(y_range[-1] - y_range[0]), color_mapper=mapper) color_bar = bm.ColorBar( color_mapper=mapper, width=7, location=(0, 0), formatter=bm.BasicTickFormatter( precision=1), #deleting unnecessary floating numbers ticker=bm.BasicTicker(desired_num_ticks=4), label_standoff=14, major_label_text_font_size='12pt', border_line_color=None, padding=2, bar_line_color='black') fig[comp].add_layout(color_bar, 'right') # Basic plots else: gridCC = _gridNodalToCellCentered(grid, cells) x_range = grid[0] * xscale #setting x coordinates y_range = grid[1] * yscale #setting y coordinates if logz: tmp = np.array(values[..., comp]) if vmin is not None or vmax is not None: for i in range(tmp.shape[0]): for j in range(tmp.shape[1]): if vmin and tmp[i, j] < vmin: tmp[i, j] = vmin #end if vmax and tmp[i, j] > vmax: tmp[i, j] = vmax #end #end if vmin is not None: vminTemp = vmin else: vminTemp = np.amin(values[..., comp]) #end if vmax is not None: vmaxTemp = vmax else: vmaxTemp = np.amax(values[..., comp]) #end mapper = bm.LogColorMapper(palette='Inferno256', low=vminTemp, high=vmaxTemp) fig[comp].image(image=[tmp.transpose()], x=x_range[0], y=y_range[0], dw=(x_range[-1] - x_range[0]), dh=(y_range[-1] - y_range[0]), color_mapper=mapper) color_bar = bm.ColorBar( color_mapper=mapper, #adding a colorbar width=7, location=(0, 0), formatter=bm.BasicTickFormatter( precision=1 ), #deleting unnecessary floating numbers ticker=bm.BasicTicker(), label_standoff=13, major_label_text_font_size='12pt', border_line_color=None, padding=2, bar_line_color='black') fig[comp].add_layout(color_bar, 'right') else: mapper = bm.LinearColorMapper(palette='Inferno256', low=np.amin(values[..., comp]), high=np.amax(values[..., comp])) fig[comp].image(image=[values[..., comp].transpose()], x=x_range[0], y=y_range[0], dw=(x_range[-1] - x_range[0]), dh=(y_range[-1] - y_range[0]), color_mapper=mapper) color_bar = bm.ColorBar( color_mapper=mapper, #adding a colorbar width=7, location=(0, 0), formatter=bm.BasicTickFormatter( precision=1 ), #deleting unnecessary floating numbers ticker=bm.BasicTicker(desired_num_ticks=4), label_standoff=13, major_label_text_font_size='12pt', border_line_color=None, padding=2, bar_line_color='black') fig[comp].add_layout(color_bar, 'right') #end #end else: raise ValueError("{:d}D data not yet supported".format(numDims)) #end #-- Additional Formatting ------------------------------------ if not quiver: fig[comp].x_range.range_padding = 0 if numDims == 2: fig[comp].y_range.range_padding = 0 #end #end if legend: if numDims == 2: x_range = grid[0] * xscale y_range = grid[1] * yscale #The legends are not embedded into the plot but the text numbers on the top of plots. Refer to 1D line plot. legend_number = bm.Label( x=x_range[0] + (x_range[-1] - x_range[0]) * 0.005, y=y_range[-1] - (y_range[-1] - y_range[0]) * 0.115, text=label, render_mode='css', background_fill_color='white', background_fill_alpha=0.9, border_line_cap='round') fig[comp].add_layout(legend_number) #end #end if title: if comp < numCols: fig[comp].title.text = title #end #end if not legend: if numDims == 1: fig[comp].legend.visible = False #end #end gp = bl.gridplot(children=fig, toolbar_location='right', ncols=numCols, merge_tools=True) return gp
def plot_2d(data, summary_axis, time_axis): ''' Plot variance analysis along 2D Inputs data [array] Voxelwise data Can be scalar (vw_variance) or binary (regressor) summary_axis [tuple] One or more axes to summarise variance time_axis [scalar] Axis along which time is encoded Outputs handle [object] Figure handle ''' # Safety check if data.ndim - 2 != len(summary_axis): raise TypeError('Error: incorrect number of summary axes specified.') # Mean variance across summary axes y = np.mean(data, axis=summary_axis, keepdims=True) # Make time the 0th axis, squeeze and transpose # y = (slice, time) y = np.moveaxis(y, time_axis, 0) y = y.squeeze() y = y.T # Force data into float type y = y.astype(float) # Create figure handle = plotting.figure(plot_width=800, plot_height=500, title='', x_axis_label='Time (TR)', y_axis_label='Slice', tools='pan,box_zoom,reset', tooltips=[('x', '$x'), ('y', '$y'), ('value', '@image')]) # If the array is binary, set colour mapper to b/w # If it's not binary, use a continuous palette if np.array_equal(y, y.astype(bool)): # Grayscale colormap color_mapper = models.LinearColorMapper( palette=palettes.grey(2)[::-1], low=0, high=1, ) else: # Continuous colormap color_mapper = models.LinearColorMapper( palette=palettes.Viridis256, low=0, high=np.max(y), ) # Add image handle.image(image=[y], x=0, y=0, dh=y.shape[0], dw=y.shape[1], color_mapper=color_mapper, level='image') # Create colorbar colorbar = models.ColorBar( color_mapper=color_mapper, label_standoff=12, border_line_color=None, location=(0, 0), ticker=models.AdaptiveTicker(), ) # Add colorbar handle.add_layout(colorbar, 'right') # Tidy handle.x_range.range_padding = 0 handle.y_range.range_padding = 0 handle.grid.grid_line_width = 0.5 handle.title.align = 'center' handle.xaxis.axis_label_text_align = 'center' handle.yaxis.axis_label_text_align = 'center' handle.xaxis.axis_label_text_font_size = '10pt' handle.yaxis.axis_label_text_font_size = '10pt' handle.xaxis.axis_label_text_font_style = 'normal' handle.yaxis.axis_label_text_font_style = 'normal' # Return return handle