Plot.py 4.06 KiB
# Plot.py -- Pamhyr
# Copyright (C) 2023-2024  INRAE
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <https://www.gnu.org/licenses/>.

# -*- coding: utf-8 -*-

import logging

from tools import timer, trace
from View.Tools.PamhyrPlot import PamhyrPlot
from View.Tools.Plot.OnPickEvent import OnpickEvent

from PyQt5.QtCore import (
    QCoreApplication
)

_translate = QCoreApplication.translate

logger = logging.getLogger()


class Plot(PamhyrPlot):
    def __init__(self, canvas=None, trad=None, data=None, toolbar=None,
                 table=None, parent=None):
        super(Plot, self).__init__(
            canvas=canvas,
            trad=trad,
            data=data,
            toolbar=toolbar,
            parent=parent
        )

        self._table = table

        self.line_xy = []
        self.line_gl = []

        self.label_x = self._trad["unit_kp"]
        self.label_y = self._trad["unit_height"]

        self.before_plot_selected = None
        self.plot_selected = None
        self.after_plot_selected = None

        self._isometric_axis = False

    @timer
    def draw(self):
        self.init_axes()

        x = self.data.get_station()
        y = self.data.z()
        x_carto = self.data.x()
        y_carto = self.data.y()

        if (len(x_carto) < 3 or len(y_carto) < 3 or
                len(x) < 3):
            # Noting to do in this case
            return

        gl = map(lambda p: p.name, self.data.points)

        self.profile_line2D, = self.canvas.axes.plot(
            x, y, color=self.color_plot,
            lw=1.5, markersize=7, marker='+',
            picker=30
        )

        # Add label on graph
        self.annotation = []
        for i, name in enumerate(list(gl)):
            annotation = self.canvas.axes.annotate(
                name, (x[i], y[i]),
                horizontalalignment='left',
                verticalalignment='top',
                annotation_clip=True,
                fontsize=10, color='black'
            )
            annotation.set_position((x[i], y[i]))
            annotation.set_color("black")
            self.annotation.append(annotation)

        al = 8.
        arrowprops = dict(
            clip_on=True,
            headwidth=5.,
            facecolor='k'
        )
        kwargs = dict(
            xycoords='axes fraction',
            textcoords='offset points',
            arrowprops=arrowprops,
        )

        self.canvas.axes.annotate("", (1, 0), xytext=(-al, 0), **kwargs)
        self.canvas.axes.annotate("", (0, 1), xytext=(0, -al), **kwargs)

        self.canvas.axes.spines[['top', 'right']].set_color('none')
        self.canvas.axes.yaxis.tick_left()
        self.canvas.axes.xaxis.tick_bottom()
        self.canvas.axes.set_facecolor('#F9F9F9')
        self.canvas.figure.patch.set_facecolor('white')

        self.onpick_event = OnpickEvent(
            self.canvas.axes,
            x, y, x_carto, y_carto,
            self._table
        )
        self.canvas.figure.canvas\
                          .mpl_connect(
                              'pick_event',
                              self.onpick_event.onpick
                          )

        self.onclick_event = OnpickEvent(
            self.canvas.axes,
            x, y, x_carto, y_carto,
            self._table
        )
        self.canvas.figure.canvas\
                          .mpl_connect(
                              'button_press_event',
                              self.onclick_event.onclick
                          )

        self.idle()

    @timer
    def update(self):
        self.draw()