Example #1
0
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
Example #2
0
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
Example #3
0
    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
Example #4
0
    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
Example #5
0
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)
Example #6
0
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
Example #7
0
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
Example #8
0
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
Example #9
0
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():
Example #10
0
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
Example #11
0
}

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,
Example #12
0
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
Example #13
0
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
Example #14
0
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