Ejemplo n.º 1
0
def outside_legend(
    fig: plt.Figure,
    ax: plt.Axes,
    legend_padding: float = 0.04,
    legend_height: float = 0.3,
    **kwargs,
) -> None:
    """Plots a legend immediately above the figure axes.

    Args:
        fig: The figure to plot the legend on.
        ax: The axes to plot the legend above.
        legend_padding: Padding between top of axes and bottom of legend, in inches.
        legend_height: Height of legend, in inches.
        **kwargs: Passed through to `fig.legend`.
    """
    _width, height = fig.get_size_inches()
    pos = ax.get_position()
    legend_left = pos.x0
    legend_right = pos.x0 + pos.width
    legend_width = legend_right - legend_left
    legend_bottom = pos.y0 + pos.height + legend_padding / height
    legend_height = legend_height / height
    bbox = (legend_left, legend_bottom, legend_width, legend_height)
    fig.legend(
        loc="lower left",
        bbox_to_anchor=bbox,
        bbox_transform=fig.transFigure,
        mode="expand",
        **kwargs,
    )
Ejemplo n.º 2
0
def _mpl_figure_to_rgb_img(fig: plt.Figure, height, width):
    fig.set_dpi(100)
    fig.set_size_inches(width / 100, height / 100)

    canvas = fig.canvas
    canvas.draw()
    width, height = np.round(fig.get_size_inches() * fig.get_dpi()).astype(int)
    # image = np.fromstring(fig.canvas.tostring_rgb(), dtype='uint8')

    img = np.fromstring(canvas.tostring_rgb(),
                        dtype='uint8').reshape(height, width, 3)
    plt.close(fig)
    return img
Ejemplo n.º 3
0
def _(
    figure: Figure,
    scale: str = "down",
    inherit_font: bool = True,
    tight_layout: bool = True,
    bbox_inches: str = None,
) -> SVGContentConfiguration:
    if tight_layout:
        figure.tight_layout()

    fig_size = figure.get_size_inches()
    with io.StringIO() as str_io:
        figure.savefig(str_io, format="svg", transparent=True, bbox_inches=bbox_inches)
        svg = str_io.getvalue()
    return SVGContentConfiguration(
        data=clean_svg(
            svg,
            scale=scale,
            width=fig_size[0],
            height=fig_size[1],
            inherit_font=inherit_font,
        )
    )
Ejemplo n.º 4
0
Archivo: ui.py Proyecto: jiejohn/paddle
class MplView(FigureCanvas, QWidget):
    """
    Base class for matplotlib based views. This handles graph canvas setup, toolbar initialisation
    and figure save options.
    """
    is_floatable_view = True
    is_mpl_toolbar_enabled = True

    """Ultimately, this is a QWidget (as well as a FigureCanvasAgg, etc.)."""
    def __init__(self, parent, width=5, height=5, dpi=96, **kwargs):

        self.v = parent

        self.fig = Figure(figsize=(width, height), dpi=dpi)
        self.ax = self.fig.add_subplot(111)
        FigureCanvas.__init__(self, self.fig)

        self.setParent(parent)

        FigureCanvas.setSizePolicy(self,
                                   QSizePolicy.Expanding,
                                   QSizePolicy.Expanding)
        FigureCanvas.updateGeometry(self)
        
        # Install navigation handler; we need to provide a Qt interface that can handle multiple 
        # plots in a window under separate tabs
        # self.navigation = MplNavigationHandler(self)

        self._current_axis_bounds = None

    def generate(self):
        pass

    def saveAsImage(self, settings): # Size, dots per metre (for print), resample (redraw) image
        filename, _ = QFileDialog.getSaveFileName(self, 'Save current figure', '',  "Tagged Image File Format (*.tif);;\
                                                                                     Portable Document File (*.pdf);;\
                                                                                     Encapsulated Postscript File (*.eps);;\
                                                                                     Scalable Vector Graphics (*.svg);;\
                                                                                     Portable Network Graphics (*.png)")

        if filename:
            size = settings.get_print_size('in')
            dpi = settings.get_dots_per_inch()
            prev_size = self.fig.get_size_inches()
            self.fig.set_size_inches(*size)
            
            self.fig.savefig(filename, dpi=dpi)
            self.fig.set_size_inches(*prev_size)
            self.redraw()

    def get_size_inches(self, dpi):
        s = self.size()
        return s.width()/dpi, s.height()/dpi

    def redraw(self):
        #FIXME: Ugly hack to refresh the canvas
        self.resize( self.size() - QSize(1,1) )
        self.resize( self.size() + QSize(1,1) )
        
    def resizeEvent(self,e):
        FigureCanvas.resizeEvent(self,e)


    def get_text_bbox_screen_coords(self, t):
        bbox = t.get_window_extent(self.get_renderer())        
        return bbox.get_points()

    def get_text_bbox_data_coords(self, t):
        bbox = t.get_window_extent(self.get_renderer())        
        axbox = bbox.transformed(self.ax.transData.inverted())
        return axbox.get_points()
        
    def extend_limits(self, a, b):
        # Extend a to meet b where applicable
        ax, ay = list(a[0]), list(a[1])
        bx, by = b[:, 0], b[:, 1]
   
        ax[0] = bx[0] if bx[0] < ax[0] else ax[0]
        ax[1] = bx[1] if bx[1] > ax[1] else ax[1]

        ay[0] = by[0] if by[0] < ay[0] else ay[0]
        ay[1] = by[1] if by[1] > ay[1] else ay[1]
                
        return [ax,ay]

    def adjust_tight_bbox(self, pad=0.1, extra_artists=None):
        bbox_inches = self.figure.get_tightbbox(self.renderer)
        bbox_artists = self.figure.get_default_bbox_extra_artists()

        if extra_artists is None:
            extra_artists = []
            extra_artists.extend([ax.get_legend() for ax in self.figure.axes if ax.get_legend()])

        bbox_artists.extend(extra_artists)
        bbox_filtered = []
        for a in bbox_artists:
            bbox = a.get_window_extent(self.renderer)
            if a.get_clip_on():
                clip_box = a.get_clip_box()
                if clip_box is not None:
                    bbox = Bbox.intersection(bbox, clip_box)
                clip_path = a.get_clip_path()
                if clip_path is not None and bbox is not None:
                    clip_path = clip_path.get_fully_transformed_path()
                    bbox = Bbox.intersection(bbox,
                                             clip_path.get_extents())
            if bbox is not None and (bbox.width != 0 or
                                     bbox.height != 0):
                bbox_filtered.append(bbox)

        if bbox_filtered:
            _bbox = Bbox.union(bbox_filtered)
            trans = Affine2D().scale(1.0 / self.figure.dpi)
            bbox_extra = TransformedBbox(_bbox, trans)
            bbox_inches = Bbox.union([bbox_inches, bbox_extra])

        if pad:
            bbox_inches = bbox_inches.padded(pad)

        rect = (np.array(bbox_inches.bounds).reshape(-1,2) / self.figure.get_size_inches()).flatten()

        # Adjust the rect; values <0 to +; + to zero
        xpad = -np.min((rect[0], (1-rect[2])))
        xpad = 0 if xpad < 0 else xpad
        ypad = -np.min((rect[1], (1-rect[3])))
        ypad = 0 if ypad < 0 else ypad
        rect = np.array([ xpad, ypad, 1-xpad, 1-ypad ])



        self.figure.tight_layout(rect=np.abs(rect))