Example #1
0
    def _set_figure(cls, ax: axes.Axes, index: dict, range: Sequence):
        """set figure and axes for plotting

        :params ax: matplotlib.axes.Axes object
        :params index: dict of label of points of x-axis and its index in data file. Range of x-axis based on index.value()
        :params range: range of y-axis
        """

        keys = []
        values = []
        for t in index:
            if isinstance(t, tuple):
                keys.append(t[0])
                values.append(t[1])
            elif isinstance(t, (int, float)):
                keys.append('')
                values.append(t)

        # x-axis
        ax.set_xticks(values)
        ax.set_xticklabels(keys)
        ax.set_xlim(values[0], values[-1])
        ax.set_xlabel("Wave Vector")

        # y-axis
        if range:
            ax.set_ylim(range[0], range[1])
        ax.set_ylabel(r"$E-E_{fermi}(eV)$")

        # others
        ax.grid(axis='x', lw=1.2)
        ax.axhline(0, linestyle="--", c='b', lw=1.0)
        handles, labels = ax.get_legend_handles_labels()
        by_label = OrderedDict(zip(labels, handles))
        ax.legend(by_label.values(), by_label.keys())
def plot_mods(ax: Axes, stats: Stats, most_popular_at_bottom=False, percentage=False):
    # FIXME different colors when using percentage with 10 mods
    mods_by_popularity = sorted(stats.players_by_mod.keys(),
                                key=lambda mod: stats.all_time_players_by_mod[mod], reverse=most_popular_at_bottom)
    labels = ["{} - avg. {:.2f} players".format(mod, stats.all_time_players_by_mod[mod] / len(stats.dates))
              for mod in mods_by_popularity]

    colors = ['red', 'green', 'blue', 'yellow', 'purple', 'lime', 'gray', 'cyan', 'orange', 'deeppink', 'black']
    colors = colors[0:len(mods_by_popularity)]
    colors = colors if most_popular_at_bottom else reversed(colors)
    ax.set_prop_cycle(color=colors)

    all_mods_values = np.row_stack([stats.players_by_mod[mod] for mod in mods_by_popularity])
    if percentage:
        with np.errstate(invalid='ignore'):
            all_mods_values = all_mods_values / all_mods_values.sum(axis=0) * 100
    ax.stackplot(stats.dates, all_mods_values, labels=labels, linewidth=0.1)

    if percentage:
        ax.set_ylim(bottom=0, top=100)
    else:
        ax.set_ylim(bottom=0)
    decorate_axes(ax)
    handles, labels = ax.get_legend_handles_labels()
    handles = handles if most_popular_at_bottom else reversed(handles)
    labels = labels if most_popular_at_bottom else reversed(labels)
    leg = ax.legend(handles, labels, loc='upper left', prop={'size': 10})
    leg.get_frame().set_alpha(0.5)
Example #3
0
def setup_length_dist_legend(ax_for_setup: Axes):
    """
    Set up legend for length distribution plots.

    Used for both single and multi distribution plots.
    """
    # Setup legend
    handles, labels = ax_for_setup.get_legend_handles_labels()
    labels = [fill(label, 13) for label in labels]
    lgnd = ax_for_setup.legend(
        handles,
        labels,
        loc="upper right",
        # bbox_to_anchor=(1.37, 1.02),
        ncol=2,
        columnspacing=0.3,
        # shadow=True,
        prop={"size": "large"},
        framealpha=0.8,
        facecolor="white",
    )

    # Setup legend line widths larger
    for lh in lgnd.legendHandles:
        # lh._sizes = [750]
        lh.set_linewidth(3)
Example #4
0
def Graphing_SeparateLegend(ax: axes.Axes, ncol=4) -> axes.Axes:
    fig_leg = plt.figure()
    ax_leg = fig_leg.add_subplot()
    ax_leg.legend(*ax.get_legend_handles_labels(), loc="center", ncol=ncol)
    ax_leg.axis("off")
    ax.legend().remove()

    return ax_leg
def remove_duplicated_legend_labels(axes: Axes, legend_position: str, custom_defaults: Dict[str, List[str]]):
    """Remove duplicated labels from the plot legend.

    Parameters
    ----------
    axes: Axes,
        Axes where to show the labels.
    legend_position: str,
        Legend position.
    """
    handles, labels = axes.get_legend_handles_labels()
    by_label = dict(zip(labels, handles))
    axes.legend(by_label.values(), sanitize_ml_labels(
        by_label.keys(), custom_defaults=custom_defaults), loc=legend_position)
Example #6
0
def legend_translucent(ax: Axes, values=[], loc=0, alpha=0.5, leg_kw={}):
    '''
    values = [ ["%.2f" %k for k in RES] ]

    Also, you can use the following:
    leg_kw = dict(fancybox   =True, fontsize = 9,
                  framealpha =0.5,  ncol     = 1)
    blah.plot().legend(**leg_kw )
    '''
    if ax.get_legend_handles_labels() == ([], []):
        return None

    leg = ax.legend(*values, loc=loc, fancybox=True, **leg_kw)
    leg.get_frame().set_alpha(alpha)
    return leg
Example #7
0
def _legend_with_secondary(ax1: Axes, ax2: Axes):
    lines_1, labels_1 = ax1.get_legend_handles_labels()
    lines_2, labels_2 = ax2.get_legend_handles_labels()
    lines = lines_1 + lines_2
    labels = labels_1 + labels_2
    ax1.legend(lines, labels, loc=0)
Example #8
0
class Projector(object):
    dpi = 100  # make sure that figures can be displayed pixel-precise

    css = '''
    body {
      margin:0px;
      background-color: #FFFFFF;
    }
    .panel {
      background-color: #000000;
      overflow: hidden;
    }
    .bk.frame {
      background-color: #FFFFFF;
      color: #FFFFFF;
    }
    .bk.legend {
      background-color: #16425B;
      color: #CCCCCC;
    }
    .bk.hot {
      background-color: #2896A5;
      color: #CCCCCC;
    }
    .bk.profile {
      background-color: #40C1C7;
      color: #CCCCCC;
    }
    .bk.colorbar {
      background-color: #2896A5;
      color: #CCCCCC;
    '''

    def __init__(self, calibprojector: str = None, use_panel: bool = True, p_width=1280, p_height=800,
                 show_colorbar: bool = False, position_colorbar: str = "vertical",
                 show_legend: bool = False, show_hot: bool = False,
                 show_profile: bool = False, ):
        """
        Args:
            calibprojector:
            use_panel: Automatically display
            p_width: x native resolution of the projector
            p_height: y native resolution of the projector
            show_colorbar:
            position_colorbar: "vertical" or "horizontal"
            show_legend:
            show_hot:
            show_profile
        """
        self.version = '2.2.p'
        self.ax = None
        self.figure = None
        self.json_filename = calibprojector

        # flags
        self.enable_legend = show_legend
        self.enable_hot = show_hot
        self.enable_colorbar = show_colorbar
        self.pos_colorbar = position_colorbar
        self._ratio = 10
        self.enable_profile = show_profile

        if calibprojector is None:
            self.p_width = p_width
            self.p_height = p_height
            self.p_frame_top = 50
            self.p_frame_left = 50
            self.p_frame_width = 700
            self.p_frame_height = 500
            # Colorbar
            self.col_top = 0
            self.col_left = 0 if self.pos_colorbar == "vertical" else self.p_frame_left
            self.col_width = self.p_frame_width if self.pos_colorbar == "horizontal" \
                                           else round(self.p_frame_width / self._ratio)
            self.col_height = self.p_frame_height if self.pos_colorbar == "vertical" \
                                           else round(self.p_frame_height / self._ratio)

            self.leg_width = round(self.p_frame_width/4)
            self.leg_height = round(self.p_frame_width/3)
            self.leg_top = 0
            self.leg_left = 0
        else:
            self.load_json(calibprojector)

        self._size_label_cbar = 15
        self._label = None

        # panel components (panes)
        self.panel = None
        self.frame = None
        self.legend = None
        self.hot = None
        self.profile = None
        self.colorbar = None
        self.sidebar = None
        # This is to solve issue #3. Give 0.01 ms to each Text from ax.arists to be plotted
        self._target_time = 0.00
        self._paused_time = None

        self.create_panel()
        if use_panel is True:
            self.start_server()

    @property
    def _dim_label_ax(self):
        return [0, 0, 2, 0.1] if self.pos_colorbar == "horizontal" else [0, 0, 0.1, 2]

    def create_panel(self):
        """ Initializes the matplotlib figure and empty axes according to projector calibration.

        The figure can be accessed by its attribute. It will be 'deactivated' to prevent random apperance in notebooks.
        """
        pn.extension(raw_css=[self.css])
        # Create a panel object and serve it within an external bokeh browser that will be opened in a separate window

        # In this special case, a "tight" layout would actually add again white space to the plt canvas,
        # which was already cropped by specifying limits to the axis

        self.figure = Figure(figsize=(self.p_frame_width / self.dpi, self.p_frame_height / self.dpi),
                             dpi=self.dpi)
        self.ax = Axes(self.figure, [0., 0., 1., 1.])
        self.figure.add_axes(self.ax)
        self.ax.set_axis_off()
        self.ax.get_xaxis().set_visible(False)
        self.ax.get_yaxis().set_visible(False)

        self.frame = pn.pane.Matplotlib(self.figure,
                                        width=self.p_frame_width,
                                        height=self.p_frame_height,
                                        margin=[self.p_frame_top, 0, 0, self.p_frame_left],
                                        tight=False,
                                        dpi=self.dpi,
                                        css_classes=['frame']
                                        )
        plt.close(self.figure)  # close figure to prevent inline display

        if self.enable_colorbar:
            self.create_colorbar()

        if self.enable_legend:
            self.create_legend()

        if self.enable_hot:
            self.create_hot()

        if self.enable_profile:
            self.create_profile()

        # Combine panel and deploy bokeh server
        if self.pos_colorbar == "vertical":
            self.sidebar = pn.Column(self.colorbar, self.legend, self.hot, self.profile,
                                     margin=[self.p_frame_top, 0, 0, 0],
                                     )

            self.panel = pn.Row(pn.Column(self.frame, None),
                                self.sidebar,
                                width=self.p_width,
                                height=self.p_height,
                                sizing_mode='fixed',
                                css_classes=['panel']
                                )
        elif self.pos_colorbar == "horizontal":
            self.sidebar = pn.Column(self.legend, self.hot, self.profile,
                                     margin=[self.p_frame_top, 0, 0, 0],
                                     )
            self.panel = pn.Row(pn.Column(self.frame, self.colorbar),
                                self.sidebar,
                                width=self.p_width,
                                height=self.p_height,
                                sizing_mode='fixed',
                                css_classes=['panel']
                                )
        else:
            raise AttributeError

        return True

    def create_colorbar(self):
        empty_fig_bg_cb = Figure()
        self.colorbar = pn.pane.Matplotlib(empty_fig_bg_cb,
                                           width= self.col_width,
                                           height= self.col_height,
                                           margin=[self.col_top, 0, 0, self.col_left],
                                           dpi=self.dpi*2,
                                           css_classes=['colorbar'],
                                           tight=True)

    def create_legend(self):
        empty_fig_bg_ld = Figure()
        self.legend = pn.pane.Matplotlib(empty_fig_bg_ld,
                                           width=self.leg_width,
                                           height=self.leg_height,
                                           margin=[self.leg_top, 0, 0, self.leg_left],
                                           dpi=self.dpi*2,
                                           css_classes=['legend'],
                                           tight=True)

    def create_hot(self):
        self.hot = pn.Column("### Hot area",
                             width=100,
                             height=100,
                             margin=[0, 0, 0, 0],
                             css_classes=['hot']
                             )

    def create_profile(self):
        self.profile = pn.Column("### Profile",
                                 width=100,
                                 height=100,
                                 margin=[0, 0, 0, 0],
                                 css_classes=['profile']
                                 )

    def set_colorbar(self, vmin: float, vmax: float, cmap="viridis", norm=None, label: str = None):
        """
        Create a colorbar and display the figure in the colorbar widget
        Args:
            vmin: Minimun value of the colorbar
            vmax: Maximum value of the colorbar
            cmap: Colormap of the colorbar
            norm: (optionl) Normalization, in case that not, this is internally managed
            label: Text to display as label in the colorbar
        Returns:

        """
        if self.colorbar is not None:
            if isinstance(cmap, str):
                cmap = plt.get_cmap(cmap)
            label = label if label is not None else self._label
            cb = Figure()
            ax = Axes(cb, self._dim_label_ax)
            cb.add_axes(ax)
            norm = matplotlib.colors.Normalize(vmin=vmin, vmax=vmax) if norm is None else norm
            cb1 = matplotlib.colorbar.ColorbarBase(ax, cmap=cmap, norm=norm, orientation=self.pos_colorbar)
            cb1.set_label(label, size=self._size_label_cbar) if label is not None else None
            cb1.ax.tick_params(labelsize=self._size_label_cbar)
            self.colorbar.object = cb
            self.colorbar.param.trigger("object")

    def set_legend(self, handles=None, labels=None, *args):
        """
        Create a legend with the information of frame with the ax.get_legend_handles_labels().
        External handles and labels can be used
        Returns:

        """
        if self.legend is not None:
            ld = Figure()
            if handles is None and labels is None:
                if args == ():
                    ld.legend(*self.ax.get_legend_handles_labels())
                else:
                    ld.legend(*args)
            else:
                ld.legend(labels=labels,
                          handles=handles
                          )
            self.legend.object = ld
            self.legend.param.trigger("object")


    def write_text(self, text: str = "cgre-aachen / open_AR_Sandbox"):
        """
        Display a custom text to be displayed in the middle of the sandbox
        Args:
            text: message to display
        Returns:

        """
        self.ax.texts = []
        x = (self.ax.get_xlim()[1] - self.ax.get_xlim()[0])/2
        y = (self.ax.get_ylim()[1] - self.ax.get_ylim()[0])/2
        self.ax.annotate(text, (x, y), zorder=1000000, xycoords="data", fontsize=18, ha='center',
                         va='top', wrap=True)
        self.trigger()

    def _replace_figure_with_pyplot(self):
        """Deprecated!! workaround to fix bug of no dpi"""
        figure = plt.figure(figsize=(self.p_frame_width / self.dpi, self.p_frame_height / self.dpi),
                            dpi=self.dpi)
        ax = plt.Axes(figure, [0., 0., 1., 1.])
        figure.add_axes(ax)
        plt.close(figure)  # close figure to prevent inline display
        ax.set_axis_off()
        self.figure = figure
        self.ax = ax
        self.frame.object = figure
        self.trigger()

    def start_server(self):
        """
        Display the panel object in a new browser window
        Returns:

        """
        # Check for instances and close them?
        self.panel.show(threaded=False)  # , title="Sandbox frame!")#, port = 4242, use_reloader = False)
        # TODO: check how can check if the port exist/open and overwrite it
        logger.info('Projector initialized and server started.\n'
              'Please position the browser window accordingly and enter fullscreen!')
        return True

    def clear_axes(self):
        """
        Empty the axes of the current figure and trigger the update of the figure in the panel.
        Returns:

        """
        self.ax.cla()
        self.trigger()
        return True

    def _clock(self):
        """
        To to be sure that panel have enough time to display the figure he want. Solves issue #3
        """
        ctext = [isinstance(text, matplotlib.text.Text) for text in self.ax.texts]
        coll = [isinstance(coll, matplotlib.collections.PathCollection) for coll in self.ax.collections]
        if True in ctext or True in coll:
            sec = (len(coll)+len(ctext))*self._target_time  # Give 0.005 ms to each Text from contours to be plotted
            self._paused_time = sec
            plt.pause(sec)
        else:
            self._paused_time = None

    def trigger(self):
        """
        Update the panel figure if modified 
        Returns:

        """

        # self.figure.canvas.draw_idle()  # TODO: do we need this or not?
        self.frame.param.trigger('object')
        self._clock()
        return True

    def save_json(self, file: str = 'projector_calibration.json'):
        """
        Saves the current state of the projector in a .JSON calibration file
        Args:
            file: address to save the calibration

        Returns:

        """
        with open(file, "w") as calibration_json:
            data = {'version': self.version,
                    'p_width': self.p_width,
                    'p_height': self.p_height,
                    'p_frame_top': self.p_frame_top,
                    'p_frame_left': self.p_frame_left,
                    'p_frame_width': self.p_frame_width,
                    'p_frame_height': self.p_frame_height,
                    'col_top': self.col_top,
                    'col_left': self.col_left,
                    'col_width': self.col_width,
                    'col_height': self.col_height,
                    'pos_colorbar': self.pos_colorbar,
                    'leg_top': self.leg_top,
                    'leg_left': self.leg_left,
                    'leg_width': self.leg_width,
                    'leg_height': self.leg_height,
                    }
            json.dump(data, calibration_json)
        logger.info('JSON configuration file saved: %s' % str(file))
        return True

    def load_json(self, file: str):
        """
        Load a calibration file (.JSON format) and actualizes the panel parameters
        Args:
            file: address of the calibration to load

        Returns:

        """
        def json_load(dict_data):
            if dict_data['version'] == self.version:
                self.p_width = dict_data.get('p_width')
                self.p_height = dict_data.get('p_height')
                self.p_frame_top = dict_data.get('p_frame_top')
                self.p_frame_left = dict_data.get('p_frame_left')
                self.p_frame_width = dict_data.get('p_frame_width')
                self.p_frame_height = dict_data.get('p_frame_height')
                self.col_top = dict_data.get('col_top')
                self.col_left = dict_data.get('col_left')
                self.col_width = dict_data.get('col_width')
                self.col_height = dict_data.get('col_height')
                self.pos_colorbar = dict_data.get('pos_colorbar')
                self.leg_top = dict_data.get('leg_top')
                self.leg_left = dict_data.get('leg_left')
                self.leg_width = dict_data.get('leg_width')
                self.leg_height =dict_data.get('leg_height')

                logger.info("JSON configuration loaded for projector")
            else:
                logger.warning("JSON configuration incompatible." +
                      "\nPlease select a valid calibration file or start a new calibration!")
        if os.path.isfile(file):
            with open(file) as calibration_json:
                data = json.load(calibration_json)
                json_load(data)
        else:
            data = json.loads(file)
            json_load(data)
        return True

    def calibrate_projector(self):
        self._create_widgets()
        panel = pn.Column("### Projector dashboard arrangement",
                          self._widget_p_frame_top,
                          self._widget_p_frame_left,
                          self._widget_p_frame_width,
                          self._widget_p_frame_height,
                          '<b>Save file<b>',
                          self._widget_json_filename,
                          self._widget_json_save
                          )
        return panel

    def show_widgets_sidepanels(self):
        tabs = pn.Tabs(("Colorbar", self.show_widget_colorbar()),
                       ("Legend", self.show_widget_legend()))
        return tabs

    def show_widget_colorbar(self):
        self._create_widgets_colorbar()
        panel1 = pn.Column("### Colorbar",
                           self._widgets_show_colorbar,
                           self._widget_label,
                           self._widget_refresh_col
                          )
        panel2 = pn.Column(self._widget_colorbar_ori,
                           self._widget_top_colorbar,
                           self._widget_left_colorbar,
                           self._widget_width_colorbar,
                           self._widget_height_colorbar,
                           self._widget_col_background)
        return pn.Row(panel1, panel2)

    def show_widget_legend(self):
        self._create_widgets_legend()
        panel3 = pn.Column("### Legend",
                           self._widgets_show_legend,
                           self._widget_refresh_leg)
        panel4 = pn.Column(self._widget_top_legend,
                           self._widget_left_legend,
                           self._widget_width_legend,
                           self._widget_height_legend,
                           self._widget_leg_background)
        return pn.Row(panel3, panel4)

    def _create_widgets(self):
        # projector widgets and links
        self._widget_p_frame_top = pn.widgets.IntSlider(name='Main frame top margin',
                                                        value=self.p_frame_top,
                                                        start=0,
                                                        end=self.p_height - 20)
        self._widget_p_frame_top.link(self.frame, callbacks={'value': self._callback_p_frame_top})

        self._widget_p_frame_left = pn.widgets.IntSlider(name='Main frame left margin',
                                                         value=self.p_frame_left,
                                                         start=0,
                                                         end=self.p_width - 20)
        self._widget_p_frame_left.link(self.frame, callbacks={'value': self._callback_p_frame_left})

        self._widget_p_frame_width = pn.widgets.IntSlider(name='Main frame width',
                                                          value=self.p_frame_width,
                                                          start=10,
                                                          end=self.p_width)
        self._widget_p_frame_width.link(self.frame, callbacks={'value': self._callback_p_frame_width})

        self._widget_p_frame_height = pn.widgets.IntSlider(name='Main frame height',
                                                           value=self.p_frame_height,
                                                           start=10,
                                                           end=self.p_height)
        self._widget_p_frame_height.link(self.frame, callbacks={'value': self._callback_p_frame_height})

        self._widget_json_filename = pn.widgets.TextInput(name='Choose a calibration filename:')
        self._widget_json_filename.param.watch(self._callback_json_filename, 'value', onlychanged=False)
        self._widget_json_filename.value = _calibration_dir + 'my_projector_calibration.json'

        self._widget_json_save = pn.widgets.Button(name='Save calibration')
        self._widget_json_save.param.watch(self._callback_json_save, 'clicks', onlychanged=False)

        return True

    def _create_widgets_colorbar(self):
        self._widget_colorbar_ori = pn.widgets.Select(name='Orientation Colorbar',
                                                    options=["vertical", "horizontal"],
                                                   value=self.pos_colorbar)
        self._widget_colorbar_ori.param.watch(self._callback_colorbar_ori, 'value', onlychanged=False)

        self._widgets_show_colorbar = pn.widgets.Checkbox(name='Show colorbar',
                                                          value=self.enable_colorbar)
        self._widgets_show_colorbar.param.watch(self._callback_enable_colorbar, 'value',
                                                onlychanged=False)

        self._widget_top_colorbar = pn.widgets.IntSlider(name='Top space',
                                                        value=self.col_top,
                                                        start=0,
                                                        end=self.p_height - 20)
        self._widget_top_colorbar.param.watch(self._callback_top_colorbar, 'value', onlychanged=False)

        self._widget_left_colorbar = pn.widgets.IntSlider(name='Left space',
                                                         value=self.col_left,
                                                         start=0,
                                                         end=self.p_width - 20)
        self._widget_left_colorbar.param.watch(self._callback_left_colorbar, 'value', onlychanged=False)

        self._widget_width_colorbar = pn.widgets.IntSlider(name='Width Colorbar',
                                                          value=self.col_width,
                                                          start=1,
                                                          end=self.p_width)
        self._widget_width_colorbar.param.watch(self._callback_width_colorbar, 'value', onlychanged=False)

        self._widget_height_colorbar = pn.widgets.IntSlider(name='Height colorbar',
                                                           value=self.col_height,
                                                           start=1,
                                                           end=self.p_height)
        self._widget_height_colorbar.param.watch(self._callback_height_colorbar, 'value', onlychanged=False)

        self._widget_label = pn.widgets.TextInput(name='Label of colorbar')
        self._widget_label.param.watch(self._callback_label, 'value', onlychanged=False)

        self._widget_refresh_col = pn.widgets.Button(name="Refresh label",
                                                    button_type="success")
        self._widget_refresh_col.param.watch(self._callback_refresh, 'clicks',
                                            onlychanged=False)

        self._widget_col_background = pn.widgets.ColorPicker(name='Color background colorbar', value="#2896A5")
        self._widget_col_background.param.watch(self._callback_col_background, 'value', onlychanged=False)

    def _create_widgets_legend(self):
        self._widgets_show_legend = pn.widgets.Checkbox(name='Show legend',
                                                        value=self.enable_legend)
        self._widgets_show_legend.param.watch(self._callback_enable_legend, 'value',
                                                onlychanged=False)

        self._widget_top_legend = pn.widgets.IntSlider(name='Top space',
                                                        value=self.leg_top,
                                                        start=0,
                                                        end=self.p_height - 20)
        self._widget_top_legend.param.watch(self._callback_top_legend, 'value', onlychanged=False)

        self._widget_left_legend = pn.widgets.IntSlider(name='Left space',
                                                         value=self.leg_left,
                                                         start=0,
                                                         end=self.p_width - 20)
        self._widget_left_legend.param.watch(self._callback_left_legend, 'value', onlychanged=False)

        self._widget_width_legend = pn.widgets.IntSlider(name='Width Legend',
                                                          value=self.leg_width,
                                                          start=1,
                                                          end=self.p_width)
        self._widget_width_legend.param.watch(self._callback_width_legend, 'value', onlychanged=False)

        self._widget_height_legend = pn.widgets.IntSlider(name='Height Legend',
                                                           value=self.leg_height,
                                                           start=1,
                                                           end=self.p_height)
        self._widget_height_legend.param.watch(self._callback_height_legend, 'value', onlychanged=False)

        self._widget_refresh_leg = pn.widgets.Button(name="Refresh legend",
                                                    button_type="success")
        self._widget_refresh_leg.param.watch(self._callback_refresh_leg, 'clicks',
                                            onlychanged=False)

        self._widget_leg_background = pn.widgets.ColorPicker(name='Color background colorbar', value="#16425B")
        self._widget_leg_background.param.watch(self._callback_leg_background, 'value', onlychanged=False)

    def _callback_label(self, event):
        self._label = event.new if event.new != "" else None

    def _callback_refresh(self, event):
        self.set_colorbar(0, 1, label=self._label)

    def _callback_refresh_leg(self, event):
        self.set_legend()

    def _callback_enable_colorbar(self, event):
        self.enable_colorbar = event.new
        self.set_colorbar_widget()

    def _callback_enable_legend(self, event):
        self.enable_legend = event.new
        if self.enable_legend:
            self.create_legend()
            self.sidebar.insert(1, self.legend)
        else:
            if self.legend is not None:
                self.sidebar.remove(self.legend) if self.legend in self.sidebar else None

    def set_colorbar_widget(self):
        if self.colorbar is not None:
            for pa in self.panel:
                if self.colorbar in pa:
                    pa.remove(self.colorbar)
                    break
        if self.enable_colorbar:
            if self.pos_colorbar == "horizontal":
                self.create_colorbar()
                self.colorbar.margin = [0, 0, 0, self.p_frame_left]
                self.panel[0].insert(1, self.colorbar)
            elif self.pos_colorbar == "vertical":
                self.create_colorbar()
                self.sidebar.insert(0, self.colorbar)
            self._widget_height_colorbar.value = self.col_height = self.p_frame_height if self.pos_colorbar == "vertical" \
                else round(self.p_frame_height / self._ratio)
            self._widget_width_colorbar.value = self.col_width = self.p_frame_width if self.pos_colorbar == "horizontal" \
                                           else round(self.p_frame_width / self._ratio)
            self._widget_left_colorbar.value = self.col_left = 0 if self.pos_colorbar == "vertical" else self.p_frame_left
            self._widget_top_colorbar.value = self.col_top = 0

    def _callback_colorbar_ori(self, event):
        self.pos_colorbar = event.new
        self.set_colorbar_widget()

    def _callback_top_colorbar(self, event):
        self.colorbar.margin[0] = event.new
        self.colorbar.param.trigger('object')

    def _callback_left_colorbar(self, event):
        self.colorbar.margin[-1] = event.new
        self.colorbar.param.trigger('object')

    def _callback_width_colorbar(self, event):
        self.colorbar.width = event.new
        self.colorbar.param.trigger('object')

    def _callback_height_colorbar(self, event):
        self.colorbar.height = event.new
        self.colorbar.param.trigger('object')

    def _callback_top_legend(self, event):
        self.leg_top = event.new
        self.legend.margin[0] = event.new
        self.legend.param.trigger('object')

    def _callback_left_legend(self, event):
        self.leg_left = event.new
        self.legend.margin[-1] = event.new
        self.legend.param.trigger('object')

    def _callback_width_legend(self, event):
        self.leg_width = event.new
        self.legend.width = event.new
        self.legend.param.trigger('object')

    def _callback_height_legend(self, event):
        self.leg_height = event.new
        self.legend.height = event.new
        self.legend.param.trigger('object')

    def _callback_p_frame_top(self, target, event):
        self.p_frame_top = event.new
        m = target.margin
        n = event.new
        # just changing single indices does not trigger updating of pane
        target.margin = [n, m[1], m[2], m[3]]

    def _callback_p_frame_left(self, target, event):
        self.p_frame_left = event.new
        m = target.margin
        n = event.new
        target.margin = [m[0], m[1], m[2], n]

    def _callback_p_frame_width(self, target, event):
        self.p_frame_width = event.new
        target.width = event.new
        target.param.trigger('object')

    def _callback_p_frame_height(self, target, event):
        self.p_frame_height = event.new
        target.height = event.new
        target.param.trigger('object')

    def _callback_json_filename(self, event):
        self.json_filename = event.new

    def _callback_json_save(self, event):
        if self.json_filename is not None:
            self.save_json(file=self.json_filename)

    def _callback_col_background(self, event):
        self.colorbar.background = event.new

    def _callback_leg_background(self, event):
        self.legend.background = event.new
Example #9
0
def maybe_add_legend(ax: Axes, *, loc: str = 'best') -> None:
    handles, labels = ax.get_legend_handles_labels()
    if labels:
        ax.legend(handles, labels, loc=loc)