Пример #1
0
class criarGrafico(QWidget):
    def __init__(self, parent=None):
        super(criarGrafico, self).__init__(parent)
        self.configurar()
        self.fig = plt.figure(figsize=(13.2, 2))
        self.data = self.get_data()

        self.canvas = self.create_main_frame()
        self.on_draw()

    def configurar(self):
        SMALL_SIZE = 8
        MEDIUM_SIZE = 10
        BIGGER_SIZE = 12

        plt.rc('font', size=BIGGER_SIZE)  # controls default text sizes
        plt.rc('axes', titlesize=BIGGER_SIZE)  # fontsize of the axes title
        plt.rc('axes', labelsize=MEDIUM_SIZE)  # fontsize of the x and y labels
        plt.rc('xtick', labelsize=SMALL_SIZE)  # fontsize of the tick labels
        plt.rc('ytick', labelsize=SMALL_SIZE)  # fontsize of the tick labels
        plt.rc('legend', fontsize=SMALL_SIZE)  # legend fontsize
        plt.rc('figure', titlesize=BIGGER_SIZE)  # fontsize of the figure title

    def create_main_frame(self):

        self.canvas = FigureCanvas(self.fig)
        #self.canvas.setFocusPolicy(Qt.StrongFocus)
        #self.canvas.setFocus()
        return self.canvas

    def get_data(self):
        return np.arange(50).reshape([10, 5]).copy()

    def on_draw(self):
        self.fig.clear()

        #x = np.linspace(0, 100)
        #y = 1e3*np.sin(2*np.pi*x/1e-9) # one period, 1k amplitude

        ax = self.fig.add_subplot(111,
                                  xlabel='Frames',
                                  ylabel='PERCLOS',
                                  title="Analise PERCLOS")
        #ax.plot(x, y)

        ax.get_yticks([1, 2, 3, 4, 5])

        # Change only ax2
        self.canvas.draw()
Пример #2
0
 def batch(self):
     for filename in os.listdir("dsp_4/songs"):
         songname = f'dsp_4/songs/{filename}'
         y, sr = librosa.load(songname,
                              sr=None,
                              duration=int(X / sample_rate))
         hop_length = 512
         window_size = 1024
         window = np.hanning(window_size)
         out = librosa.core.spectrum.stft(y,
                                          n_fft=window_size,
                                          hop_length=hop_length,
                                          window=window)
         out = 2 * np.abs(out) / np.sum(window)
         fig = plt.Figure()
         canvas = FigureCanvas(fig)
         ax = fig.add_subplot(111)
         p = librosa.display.specshow(librosa.amplitude_to_db(out,
                                                              ref=np.max),
                                      ax=ax,
                                      y_axis='log',
                                      x_axis='time')
         fig.savefig(f'dsp_4/spectro/{filename[:-3].replace(".", "")}.png')
         plt.clf()
         self.songArr.append(filename)
Пример #3
0
 def MixedSongPhash(self):
     data1, fs = librosa.load(self.path1,
                              sr=None,
                              duration=int(X / sample_rate))
     data2, fs2 = librosa.load(self.path2,
                               sr=None,
                               duration=int(X / sample_rate))
     data = (0.1 * self.horizontalSlider.value() * data1) + (
         (1 - 0.1 * self.horizontalSlider.value()) * data2)
     hop_length = 512
     window_size = 1024
     window = np.hanning(window_size)
     out = librosa.core.spectrum.stft(data,
                                      n_fft=window_size,
                                      hop_length=hop_length,
                                      window=window)
     out = 2 * np.abs(out) / np.sum(window)
     fig = plt.Figure()
     canvas = FigureCanvas(fig)
     ax = fig.add_subplot(111)
     p = librosa.display.specshow(librosa.amplitude_to_db(out, ref=np.max),
                                  ax=ax,
                                  y_axis='log',
                                  x_axis='time')
     fig.savefig('input.png')
     MixedSongPhash = imagehash.phash(Image.open('input.png'))
     return MixedSongPhash
Пример #4
0
    def initUI(self, parent: QWidget):
        box = QVBoxLayout()
        self.figure = plt.figure()
        self.canvas = FigureCanvas(self.figure)

        self.toolbar = NavigationToolbar(self.canvas, parent)
        box.addWidget(self.toolbar)
        box.addWidget(self.canvas)
        self.setLayout(box)
Пример #5
0
 def __init__(self, parent=None, width=5, height=4, dpi=100):
     fig = Figure(figsize=(width, height), dpi=dpi)
     self.axes = fig.add_subplot(111)
     self.compute_initial_figure()
     FigureCanvas.__init__(self, fig)
     self.setParent(parent)
     FigureCanvas.setSizePolicy(self,
     QtGui.QSizePolicy.Expanding,
     QtGui.QSizePolicy.Expanding)
     FigureCanvas.__init__(self, fig)
     self.setParent(parent)
     FigureCanvas.updateGeometry(self)
Пример #6
0
 def __init__(self, parent=None, width=5, height=4, dpi=100):
     PacientInterface.__init__(self)
     fig = Figure(figsize=(width, height), dpi=dpi)
     # self.axes = fig.add_subplot(111)
     self.fig, self.ax = pyplot.subplots()
     self.line_lap0 = None
     self.line_lap1 = None
     self.line_lap2 = None
     self.line_total = None
     self.markers0 = None
     self.markers1 = None
     self.markers2 = None
     self.markers_total = None
     self.text0 = None
     self.text1 = None
     self.text2 = None
     super(Grafica, self).__init__(self.fig)
     FigureCanvas.__init__(self, self.fig)
     FigureCanvasQTAgg.updateGeometry(self)
     self.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum)
def plot_image_grid(img_grid,
                    grid_shape,
                    file_name,
                    normalize=False,
                    header=None):
    plt.ioff()
    figure = Figure(figsize=(10, 10))
    canvas = FigureCanvas(figure)
    for y in range(grid_shape[0]):
        for x in range(grid_shape[1]):
            img = img_grid[y][x]
            if normalize:
                min_ = np.min(img)
                max_ = np.max(img)
                img = (img - min_) / (max_ - min_)
            ax = figure.add_subplot(grid_shape[0], grid_shape[1],
                                    (y * grid_shape[1]) + x + 1)
            ax.set_axis_off()
            ax.imshow(img, interpolation='nearest')
            if y == 0 and header is not None:
                ax.set_title(header[x])

    canvas.print_figure(os.path.join('../results/', file_name))
Пример #8
0
import numpy as np

# Initialize `x` and `y`
x = np.ones((3,4))
y = np.ones((3,1))

# Add `x` and `y`
z = x - y
print(z)
print('beda-'*4)

print(np.sqrt(z))

import matplotlib.pyplot as plt
print(sandy)
x = sandy[0:]
print('x'*4)
print(x)
print('x'*4)

from pandas import Series
from matplotlib import pyplot
series = Series.from_csv('data.txt')
pyplot.plot(series)
pyplot.show()

#DJANGO APP
fig = Figure()
canvas = FigureCanvas(fig)
response = HttpResponse( content_type = 'image/png')
canvas.print_png(response)
Пример #9
0
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")

        self.centralWidget = QtWidgets.QWidget(MainWindow)
        self.centralWidget.setObjectName("centralWidget")

        self.statusBar()
        self.mainMenu = self.menuBar()
        self.saveMenu = self.mainMenu.addMenu('Сохранить результат')

        self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.centralWidget)
        self.horizontalLayout_2.setContentsMargins(11, 11, 11, 11)
        self.horizontalLayout_2.setSpacing(6)
        self.horizontalLayout_2.setObjectName("horizontalLayout_2")
        self.horizontalLayout = QtWidgets.QHBoxLayout()
        self.horizontalLayout.setSpacing(6)
        self.horizontalLayout.setObjectName("horizontalLayout")
        self.verticalLayout = QtWidgets.QVBoxLayout()
        self.verticalLayout.setSpacing(6)
        self.verticalLayout.setObjectName("verticalLayout")
        self.verticalLayout_2 = QtWidgets.QVBoxLayout()
        self.verticalLayout_2.setSpacing(6)
        self.verticalLayout_2.setObjectName("verticalLayout_2")

        self.labelFormula = QtWidgets.QLabel(self.centralWidget)
        self.labelFormula.setMinimumSize(QtCore.QSize(150, 0))
        self.labelFormula.setMaximumSize(QtCore.QSize(16777215, 20))
        self.labelFormula.setObjectName("label")
        self.verticalLayout_2.addWidget(self.labelFormula)

        self.label = QtWidgets.QLabel(self.centralWidget)
        self.label.setMinimumSize(QtCore.QSize(150, 0))
        self.label.setMaximumSize(QtCore.QSize(16777215, 20))
        self.label.setObjectName("label")
        self.verticalLayout_2.addWidget(self.label)
        self.spinBoxAlpha = QtWidgets.QDoubleSpinBox(self.centralWidget)
        self.spinBoxAlpha.setMinimumSize(QtCore.QSize(120, 0))
        self.spinBoxAlpha.setProperty("value", 1.0)
        self.spinBoxAlpha.setObjectName("spinBoxAlpha")
        self.verticalLayout_2.addWidget(self.spinBoxAlpha)
        self.verticalLayout.addLayout(self.verticalLayout_2)
        self.verticalLayout_3 = QtWidgets.QVBoxLayout()
        self.verticalLayout_3.setSpacing(6)
        self.verticalLayout_3.setObjectName("verticalLayout_3")
        self.label_2 = QtWidgets.QLabel(self.centralWidget)
        self.label_2.setObjectName("label_2")
        self.verticalLayout_3.addWidget(self.label_2)
        self.horizontalLayout_3 = QtWidgets.QHBoxLayout()
        self.horizontalLayout_3.setSpacing(6)
        self.horizontalLayout_3.setObjectName("horizontalLayout_3")
        self.SpinBoxStartX = QtWidgets.QDoubleSpinBox(self.centralWidget)
        self.SpinBoxStartX.setProperty("value", 2.0)
        self.SpinBoxStartX.setObjectName("SpinBoxStartX")
        self.SpinBoxStartX.setMinimum(-100.0)
        self.SpinBoxStartX.setMaximum(100.0)
        self.horizontalLayout_3.addWidget(self.SpinBoxStartX)
        self.SpinBoxStartY = QtWidgets.QDoubleSpinBox(self.centralWidget)
        self.SpinBoxStartY.setMinimum(-100.0)
        self.SpinBoxStartY.setMaximum(100.0)
        self.SpinBoxStartY.setProperty("value", 5.0)
        self.SpinBoxStartY.setObjectName("SpinBoxStartY")
        self.horizontalLayout_3.addWidget(self.SpinBoxStartY)
        self.verticalLayout_3.addLayout(self.horizontalLayout_3)
        self.verticalLayout.addLayout(self.verticalLayout_3)
        self.verticalLayout_5 = QtWidgets.QVBoxLayout()
        self.verticalLayout_5.setSpacing(6)
        self.verticalLayout_5.setObjectName("verticalLayout_5")
        self.label_3 = QtWidgets.QLabel(self.centralWidget)
        self.label_3.setObjectName("label_3")
        self.verticalLayout_5.addWidget(self.label_3)
        self.SpinBoxStepLen = QtWidgets.QDoubleSpinBox(self.centralWidget)
        self.SpinBoxStepLen.setSingleStep(0.1)
        self.SpinBoxStepLen.setProperty("value", 0.1)
        self.SpinBoxStepLen.setObjectName("SpinBoxStepLen")
        self.SpinBoxStepLen.setMaximum(10.0)
        self.verticalLayout_5.addWidget(self.SpinBoxStepLen)
        self.verticalLayout.addLayout(self.verticalLayout_5)
        self.verticalLayout_9 = QtWidgets.QVBoxLayout()
        self.verticalLayout_9.setSpacing(6)
        self.verticalLayout_9.setObjectName("verticalLayout_9")
        self.label_4 = QtWidgets.QLabel(self.centralWidget)
        self.label_4.setObjectName("label_4")
        self.verticalLayout_9.addWidget(self.label_4)
        self.SpinBoxStepCount = QtWidgets.QSpinBox(self.centralWidget)
        self.SpinBoxStepCount.setProperty("value", 10)
        self.SpinBoxStepCount.setObjectName("SpinBoxStepCount")
        self.SpinBoxStepCount.setMaximum(500.0)
        self.verticalLayout_9.addWidget(self.SpinBoxStepCount)
        self.verticalLayout.addLayout(self.verticalLayout_9)
        self.verticalLayout_4 = QtWidgets.QVBoxLayout()
        self.verticalLayout_4.setSpacing(6)
        self.verticalLayout_4.setObjectName("verticalLayout_4")
        self.label_5 = QtWidgets.QLabel(self.centralWidget)
        self.label_5.setObjectName("label_5")
        self.verticalLayout_4.addWidget(self.label_5)
        self.ComboBoxMethodName = QtWidgets.QComboBox(self.centralWidget)
        self.ComboBoxMethodName.setObjectName("ComboBoxMethodName")
        self.ComboBoxMethodName.addItem("")
        self.ComboBoxMethodName.addItem("")
        self.ComboBoxMethodName.addItem("")
        self.ComboBoxMethodName.addItem("")
        self.ComboBoxMethodName.addItem("")
        self.ComboBoxMethodName.addItem("")
        self.verticalLayout_4.addWidget(self.ComboBoxMethodName)
        self.verticalLayout.addLayout(self.verticalLayout_4)
        spacerItem = QtWidgets.QSpacerItem(10, 20, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
        self.verticalLayout.addItem(spacerItem)
        self.verticalLayout_10 = QtWidgets.QVBoxLayout()
        self.verticalLayout_10.setSpacing(6)
        self.verticalLayout_10.setObjectName("verticalLayout_10")
        self.ButtonCalculate = QtWidgets.QPushButton(self.centralWidget)
        self.ButtonCalculate.setObjectName("ButtonCalculate")
        self.verticalLayout_10.addWidget(self.ButtonCalculate)
        self.verticalLayout.addLayout(self.verticalLayout_10)
        self.horizontalLayout.addLayout(self.verticalLayout)

        self.tableView = QtWidgets.QTableView(self.centralWidget)
        self.tableView.setMinimumSize(QtCore.QSize(400, 400))
        self.tableView.setObjectName("tableView")

        self.figure = plt.figure()
        self.figure.set_facecolor("none")
        self.canvas = FigureCanvas(self.figure)
        self.toolbar = NavigationToolbar(self.canvas, self)
        self.widgetPlot = QtWidgets.QWidget()
        self.widgetPlot.setMinimumSize(QtCore.QSize(400, 400))
        layout = QtWidgets.QVBoxLayout()
        self.widgetPlot.setLayout(layout)

        layout.addWidget(self.canvas)
        layout.addWidget(self.toolbar)

        self.splitter = QSplitter(Qt.Horizontal)
        self.splitter.addWidget(self.tableView)
        self.splitter.addWidget(self.widgetPlot)

        self.horizontalLayout.addWidget(self.splitter)
        self.horizontalLayout_2.addLayout(self.horizontalLayout)
        MainWindow.setCentralWidget(self.centralWidget)

        self.menuBar = QtWidgets.QMenuBar(MainWindow)
        self.menuBar.setGeometry(QtCore.QRect(0, 0, 1093, 21))
        self.menuBar.setObjectName("menuBar")
        self.menu = QtWidgets.QMenu(self.menuBar)
        self.menu.setObjectName("menu")
        self.menu_2 = QtWidgets.QMenu(self.menuBar)
        self.menu_2.setObjectName("menu_2")
        MainWindow.setMenuBar(self.menuBar)

        self.action = QtWidgets.QAction(MainWindow)
        self.action.setObjectName("action")
        self.menu.addAction(self.action)


        self.action_3 = QtWidgets.QAction(MainWindow)
        self.action_3.setObjectName("action_3")
        self.menu_2.addAction(self.action_3)

        self.action_4 = QtWidgets.QAction(MainWindow)
        self.action_4.setObjectName("action_4")
        self.menu_2.addAction(self.action_4)

        self.menuBar.addAction(self.menu.menuAction())
        self.menuBar.addAction(self.menu_2.menuAction())

        self.retranslateUi(MainWindow)
        self.ComboBoxMethodName.setCurrentIndex(0)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)
 def __init__(self, n_rows=1, n_cols=1):
     self.fig = Figure(
         figsize=(self.subplot_width * n_cols + self.padding,
                  self.subplot_height * n_rows + self.padding),
         edgecolor='white')
     self.canvas = FigureCanvas(self.fig)
nimages = 30
imgs = imageDataset.load_training_data(batches='data_batch_1')[:nimages]
detectors = [
    ('Sift', cv2.xfeatures2d.SIFT_create()),
    ('Surf', cv2.xfeatures2d.SURF_create(hessianThreshold=300)),
    ('Star', cv2.xfeatures2d.StarDetector_create()),
    ('Brisk', cv2.BRISK_create()),
    ('MSER', cv2.MSER_create()),
    ('Kaze', cv2.KAZE_create()),
    # ('AKaze', cv2.AKAZE_create())
]

plt.ioff()
figure = Figure(figsize=(30, 30))
canvas = FigureCanvas(figure)


def drawKeyPoints(original, gray, kp):
    outImg = original.copy()
    cv2.drawKeypoints(gray,
                      kp,
                      outImg,
                      color=(255, 0, 0),
                      flags=cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS)
    return outImg


cols = len(detectors) + 2
for im_i in range(len(imgs)):
    im = imgs[im_i]
Пример #12
0
    def create_main_frame(self):

        self.canvas = FigureCanvas(self.fig)
        #self.canvas.setFocusPolicy(Qt.StrongFocus)
        #self.canvas.setFocus()
        return self.canvas
Пример #13
0
    def plot(self, features, output_path):
        """
        Plots the features: International SIGMETs, US SIGMETs, US AIRMETs and METARS on the map with which this
        class was instantiated.

        :param features: Feature object containing the parsed GEOJSON data
        :param output_path: Path to where the plot will be saved. Only PNG supported for now!
        :return:
        """
        self._log.debug("Plotting features onto axis")

        # Storage of return values
        texts = []
        plotting_failed = []
        info = {}

        ax = self._plot_definition.ax
        data_crs = ccrs.PlateCarree()

        def plot_features(features, label_property, text_property):
            """
            Plots a collection of features onto the map.

            :param features: The list of GEOJSON features
            :param label_property: Field in features[i]["properties"] which contains the label to be plotted onto the map
            :param text_property: Field in features[i]["properties"] which will be added to the infos.
            :return: Information dictionary { idx: info_text, ... }
            """
            patches = []
            patches_unkown = []
            for feat in features:
                try:
                    plot_one_feature(feat, label_property, patches,
                                     patches_unkown, text_property)
                except ValueError:
                    plotting_failed.append(feat['properties'][text_property])
                    self._log.warning("Plotting of feature=%s failed", feat)

            ax.add_collection(
                PatchCollection(patches,
                                facecolor=self._color_scheme.SIGMET_COLOR,
                                edgecolor=self._color_scheme.SIGMET_COLOR,
                                linewidths=1.5,
                                alpha=self._color_scheme.SIGMET_ALPHA,
                                zorder=40,
                                transform=data_crs))
            ax.add_collection(
                PatchCollection(
                    patches_unkown,
                    facecolor=self._color_scheme.SIGMET_UNKNOWN_COLOR,
                    linestyle='dashed',
                    edgecolor=self._color_scheme.SIGMET_UNKNOWN_COLOR,
                    hatch="/",
                    linewidths=1.5,
                    alpha=self._color_scheme.SIGMET_UNKNOWN_ALPHA,
                    zorder=39,
                    transform=data_crs))

        def plot_one_feature(feat, label_property, patches, patches_unkown,
                             text_property):
            """
            Plots one feature. If the feature is a point it will be plotted straight onto the map.

            If it is a polygon it will be added to patches

            :param feat: Feature to be plotted
            :param label_property: Field in feat["properties"] which contains the label to be plotted on the map
            :param patches: Patches collection to which the patch will be appended
            :param patches_unknown: Patches collection with unkown geometry
            :param text_property: Field in feat["properties"] which contains the text will be added to the info
            :return: Information dictionary with one element { idx: info_text }
            """
            if feat["geometry"]["type"] == "Polygon":
                # convert the geometry to shapely
                geom_raw = asShape(feat["geometry"])
                if len(geom_raw.shell) > 2:
                    geom = geom_raw.buffer(0)
                    label_geometry(geom, feat, label_property, text_property)

                    if feat["properties"].get("geom", "") == "UNK":
                        patches_unkown.append(PolygonPatch(geom))
                    else:
                        patches.append(PolygonPatch(geom))
                else:
                    self._log.warning(
                        "Encountered feature which had less than 2 elements in its shell feature=%s",
                        feat)
            elif feat["geometry"]["type"] == "Point":
                geom = Point(feat["geometry"]["coordinates"][0],
                             feat["geometry"]["coordinates"][1])
                ax.plot(geom.x,
                        geom.y,
                        'o',
                        color=self._color_scheme.SIGMET_COLOR,
                        markersize=8,
                        zorder=35,
                        transform=data_crs)
                label_geometry(geom, feat, label_property, text_property)
            else:
                self._log.error(
                    "Encountered geometry which was neither a polygon nor a point. feature=%s",
                    feat)
                raise ValueError(
                    'Geometry type was neither Polygon nor Point.')

        def find_text(x, y):
            for text in texts:
                text_x, text_y = text.get_position()
                if text_x == x and text_y == y:
                    return text
            return None

        def label_geometry(geom, feat, label_property, text_property):
            """
            Labels one geometry elements. Usually a  SIMGET or AIRMET patch.

            The label will be placed in the centroid of the visible part of geom.

            :param geom: Geometry to be labeled.
            :param feat: GEOJSON Feature
            :param label_property: Field in feat["properties"] which contains the label to be plotted on the map
            :param text_property: Field in feat["properties"] which contains the text will be added to the info
            :return: Information dictionary with one element { idx: info_text }
            """
            centroid = geom.intersection(
                self._plot_definition.region_box).centroid

            if geom.intersects(self._plot_definition.region_box):
                idx = len(info) + 1
                label = feat["properties"][label_property]
                label = self._color_scheme.TEXT_REPLACEMENT.get(label, label)
                text = label + "\n" + str(idx) + "."

                text_x, text_y = self._plot_definition.projection.transform_point(
                    centroid.x, centroid.y, data_crs)
                conflicting_text = find_text(text_x, text_y)
                if conflicting_text:
                    self._log.debug("Resolving conflicting text")
                    r = get_renderer(self._plot_definition.ax.get_figure())
                    bbox = get_bboxes([conflicting_text], r, (1.0, 1.0), ax)
                    text_x = text_x - bbox[0].width / 10
                    text_y = text_y - bbox[0].height / 10

                new_text = ax.text(text_x,
                                   text_y,
                                   text,
                                   horizontalalignment='center',
                                   verticalalignment='center',
                                   zorder=50,
                                   fontweight="heavy",
                                   fontsize=8)
                texts.append(new_text)
                info[idx] = feat["properties"][text_property]

        def plot_metars(metar_features):
            """
            Plots metars on the map.

            :param metar_features: GEOJSON METAR feature list
            :return:
            """
            self._log.debug("Plotting METARs")

            for index, feat in metar_features.iterrows():
                geom = Point(feat['longitude'], feat['latitude'])

                if self._plot_definition.region_box.contains(geom):
                    label = feat['flight_category']
                    color = self._color_scheme.METAR_FLIGHT_CATEGORY_COLORS.get(
                        label, self._color_scheme.METAR_COLOR_UNKOWN)

                    age = datetime.now(timezone.utc) - dateutil.parser.parse(
                        feat['observation_time'])
                    age_m = age.total_seconds() / 60
                    alpha_age_factor = min(1, -1 / 90 * age_m + 4 / 3)
                    alpha = self._color_scheme.METAR_ALPHA * alpha_age_factor

                    ax.plot(geom.x,
                            geom.y,
                            'o',
                            color=color,
                            markersize=4,
                            zorder=30,
                            alpha=alpha,
                            transform=data_crs)

        plot_features(features.sigmets_international["features"], "hazard",
                      "rawSigmet")
        plot_features(features.sigmets_us["features"], "hazard",
                      "rawAirSigmet")
        plot_features(features.cwa_us["features"], "hazard", "cwaText")

        plot_metars(features.metars)

        adjust_text(texts,
                    ha='center',
                    va='center',
                    expand_text=(0.9, 0.9),
                    autoalign=False,
                    on_basemap=True,
                    text_from_points=False,
                    arrowprops=dict(arrowstyle='->',
                                    color='0.15',
                                    shrinkA=3,
                                    shrinkB=3,
                                    connectionstyle="arc3,rad=0."),
                    force_text=(0.8, 0.8))

        self._plot_legend(ax, plotting_failed)

        canvas = FigureCanvas(self._plot_definition.fig)
        canvas.print_figure(output_path,
                            format="png",
                            pad_inches=0.2,
                            bbox_inches="tight",
                            bbox_extra_artists=[],
                            dpi=90)

        return PlotResult(output_path, info, plotting_failed)