Plot: Start refactoring with Geometry.PlotXY at exemple.

setup.py
Pierre-Antoine Rouby 2024-02-14 15:15:08 +01:00
parent 32886c5034
commit e1e5279366
4 changed files with 361 additions and 196 deletions

View File

@ -28,7 +28,7 @@ _translate = QCoreApplication.translate
class PlotXY(PamhyrPlot): class PlotXY(PamhyrPlot):
def __init__(self, canvas=None, trad=None, data=None, toolbar=None, def __init__(self, canvas=None, trad=None, data=None, toolbar=None,
display_current=True, parent=None): parent=None):
super(PlotXY, self).__init__( super(PlotXY, self).__init__(
canvas=canvas, canvas=canvas,
trad=trad, trad=trad,
@ -37,19 +37,19 @@ class PlotXY(PamhyrPlot):
parent=parent parent=parent
) )
self.display_current = display_current
self.line_xy = [] self.line_xy = []
self.line_gl = [] self.line_gl = []
self.label_x = _translate("Geometry", "X (m)")
self.label_y = _translate("Geometry", "Y (m)")
self.before_plot_selected = None self.before_plot_selected = None
self.plot_selected = None self.plot_selected = None
self.after_plot_selected = None self.after_plot_selected = None
@timer @timer
def draw(self, highlight=None): def draw(self):
self.canvas.axes.cla() self.init_axes()
self.canvas.axes.grid(color='grey', linestyle='--', linewidth=0.5)
if self.data is None: if self.data is None:
return return
@ -58,89 +58,76 @@ class PlotXY(PamhyrPlot):
self._init = False self._init = False
return return
kp_min, kp_max = (-1, -1) self.draw_xy()
if highlight is not None: self.draw_gl()
kp_min, kp_max = highlight self.draw_current()
# Axes self.idle()
self.canvas.axes.set_xlabel( self._init = True
_translate("Geometry", "X (m)"),
color='black', fontsize=10
)
self.canvas.axes.set_ylabel(
_translate("Geometry", "Y (m)"),
color='black', fontsize=10
)
self.canvas.axes.axis("equal")
def draw_xy(self):
kp = self.data.get_kp_complete_profiles() kp = self.data.get_kp_complete_profiles()
# self.canvas.axes.set_xlim(
# left=min(kp), right=max(kp)
# )
# Draw line for each profile kp_min, kp_max = (-1, -1)
self.line_xy = [ if self._highlight_data is not None:
self.canvas.axes.plot( kp_min, kp_max = self._highlight_data
x, y, lw=1.,
color='b' if kp_min <= kp <= kp_max else 'r',
markersize=3, marker='+'
)
for x, y, kp in zip(
self.data.get_x(), self.data.get_y(),
kp
)
]
# Guide lines def color_hightlight(kp):
if kp_min <= kp <= kp_max:
return self.color_plot_highlight
return self.color_plot
self.line_xy = []
for x, y, kp in zip(self.data.get_x(),
self.data.get_y(),
kp):
line = self.canvas.axes.plot(
x, y,
color=color_hightlight(kp),
**self.plot_default_kargs
)
self.line_xy.append(line)
def draw_gl(self):
x_complete = self.data.get_guidelines_x() x_complete = self.data.get_guidelines_x()
y_complete = self.data.get_guidelines_y() y_complete = self.data.get_guidelines_y()
self.line_gl = [ self.line_gl = []
self.canvas.axes.plot( for x, y in zip(x_complete, y_complete):
line = self.canvas.axes.plot(
x, y, x, y,
) )
for x, y in zip(x_complete, y_complete) self.line_gl.append(line)
]
if self.display_current: def draw_current(self):
# Previous profile # Previous profile
self.before_plot_selected, = self.canvas.axes.plot( self.before_plot_selected, = self.canvas.axes.plot(
self.data.profile(0).x(), self.data.profile(0).x(),
self.data.profile(0).y(), self.data.profile(0).y(),
lw=1., markersize=3, color=self.color_plot_previous, linestyle="--",
marker='+', color="k", linestyle="--" **self.plot_default_kargs
) )
self.before_plot_selected.set_visible(False) self.before_plot_selected.set_visible(False)
# Current profile # Current profile
self.plot_selected, = self.canvas.axes.plot( self.plot_selected, = self.canvas.axes.plot(
self.data.profile(0).x(), self.data.profile(0).x(),
self.data.profile(0).y(), self.data.profile(0).y(),
lw=1., markersize=3, color=self.color_plot_current, **self.plot_default_kargs
marker='+', color="b" )
) self.plot_selected.set_visible(False)
self.plot_selected.set_visible(False)
# Next profile # Next profile
self.after_plot_selected, = self.canvas.axes.plot( self.after_plot_selected, = self.canvas.axes.plot(
self.data.profile(0).x(), self.data.profile(0).x(),
self.data.profile(0).y(), self.data.profile(0).y(),
lw=1., markersize=3, color=self.color_plot_next, linestyle='--',
marker='+', color="m", linestyle='--' **self.plot_default_kargs
) )
self.after_plot_selected.set_visible(False) self.after_plot_selected.set_visible(False)
self.canvas.axes.autoscale_view(True, True, True)
self.canvas.axes.autoscale()
self.canvas.figure.tight_layout()
self.canvas.figure.canvas.draw_idle()
if self.toolbar is not None:
self.toolbar.update()
self._init = True
@timer @timer
def update(self, ind=None): def update(self):
if not self._init: if not self._init:
self.draw() self.draw()
return return
@ -148,17 +135,16 @@ class PlotXY(PamhyrPlot):
if self.data is None: if self.data is None:
return return
self.update_gl()
self.update_current()
self.update_idle()
def update_gl(self):
self.data.compute_guidelines() self.data.compute_guidelines()
x_complete = list(self.data.get_guidelines_x()) x_complete = list(self.data.get_guidelines_x())
y_complete = list(self.data.get_guidelines_y()) y_complete = list(self.data.get_guidelines_y())
# self.line_gl = [
# self.canvas.axes.plot(
# x, y,
# )
# for x, y in zip(x_complete, y_complete)
# ]
for i in range(self.data.number_profiles): for i in range(self.data.number_profiles):
if i < len(self.line_xy): if i < len(self.line_xy):
self.line_xy[i][0].set_data( self.line_xy[i][0].set_data(
@ -170,8 +156,8 @@ class PlotXY(PamhyrPlot):
self.canvas.axes.plot( self.canvas.axes.plot(
self.data.profile(i).x(), self.data.profile(i).x(),
self.data.profile(i).y(), self.data.profile(i).y(),
lw=1., color='r', color='r',
markersize=3, marker='+' **self.plot_default_kargs
) )
) )
@ -189,7 +175,9 @@ class PlotXY(PamhyrPlot):
) )
) )
if ind is not None and self.display_current: def update_current(self):
if self._current_data_update:
ind = self._current_data
before = ind - 1 before = ind - 1
after = ind + 1 after = ind + 1
@ -215,9 +203,3 @@ class PlotXY(PamhyrPlot):
self.data.profile(after).y() self.data.profile(after).y()
) )
self.after_plot_selected.set_visible(True) self.after_plot_selected.set_visible(True)
self.canvas.axes.relim()
self.canvas.axes.autoscale()
self.canvas.axes.autoscale_view()
self.canvas.figure.tight_layout()
self.canvas.figure.canvas.draw_idle()

View File

@ -113,6 +113,11 @@ class GeometryWindow(PamhyrWindow):
table.setAlternatingRowColors(True) table.setAlternatingRowColors(True)
def setup_plots(self): def setup_plots(self):
self.setup_plots_xy()
self.setup_plots_kpc()
self.setup_plots_ac()
def setup_plots_xy(self):
self._canvas_xy = MplCanvas(width=3, height=4, dpi=100) self._canvas_xy = MplCanvas(width=3, height=4, dpi=100)
self._canvas_xy.setObjectName("canvas_xy") self._canvas_xy.setObjectName("canvas_xy")
self._toolbar_xy = PamhyrPlotToolbar( self._toolbar_xy = PamhyrPlotToolbar(
@ -124,6 +129,7 @@ class GeometryWindow(PamhyrWindow):
self._plot_layout_xy.addWidget(self._canvas_xy) self._plot_layout_xy.addWidget(self._canvas_xy)
self.plot_xy() self.plot_xy()
def setup_plots_kpc(self):
self._canvas_kpc = MplCanvas(width=6, height=4, dpi=100) self._canvas_kpc = MplCanvas(width=6, height=4, dpi=100)
self._canvas_kpc.setObjectName("canvas_kpc") self._canvas_kpc.setObjectName("canvas_kpc")
self._toolbar_kpc = PamhyrPlotToolbar( self._toolbar_kpc = PamhyrPlotToolbar(
@ -135,6 +141,7 @@ class GeometryWindow(PamhyrWindow):
self._plot_layout_kpc.addWidget(self._canvas_kpc) self._plot_layout_kpc.addWidget(self._canvas_kpc)
self.plot_kpc() self.plot_kpc()
def setup_plots_ac(self):
self._canvas_ac = MplCanvas(width=9, height=4, dpi=100) self._canvas_ac = MplCanvas(width=9, height=4, dpi=100)
self._canvas_ac.setObjectName("canvas_ac") self._canvas_ac.setObjectName("canvas_ac")
self._toolbar_ac = PamhyrPlotToolbar( self._toolbar_ac = PamhyrPlotToolbar(
@ -375,7 +382,8 @@ class GeometryWindow(PamhyrWindow):
def select_plot_xy(self, ind: int): def select_plot_xy(self, ind: int):
self.tableView.model().blockSignals(True) self.tableView.model().blockSignals(True)
self._plot_xy.update(ind=ind) self._plot_xy.current = ind
self._plot_xy.update()
self.tableView.model().blockSignals(False) self.tableView.model().blockSignals(False)
def select_plot_kpc(self, ind: int): def select_plot_kpc(self, ind: int):

View File

@ -22,17 +22,57 @@ from View.Tools.Plot.PamhyrToolbar import PamhyrPlotToolbar
class PamhyrPlot(APlot): class PamhyrPlot(APlot):
def __init__(self, data=None, trad=None, color_axes = "black"
canvas=None, toolbar=None, color_axes_grid = "grey"
color_axes_labels = "black"
color_plot = "red"
color_plot_highlight = "blue"
color_plot_previous = "black"
color_plot_current = "blue"
color_plot_next = "purple"
plot_default_kargs = {
"lw" : 1.,
"markersize" : 3,
"marker" : "+",
}
def __init__(self, data=None,
trad=None, # Translate object
canvas=None, # Use existing canvas
canvas_height=4, canvas_width=5,
canvas_dpi=100,
toolbar=None,
table=None,
parent=None): parent=None):
if canvas is None: if canvas is None:
canvas = MplCanvas() canvas = MplCanvas(
height=canvas_height, width=canvas_width,
dpi=canvas_dpi
)
self._trad = trad self._trad = trad
self._canvas = canvas self._canvas = canvas
self._toolbar = toolbar self._toolbar = toolbar
self._table = table
self._parent = parent self._parent = parent
self._label_x = "X"
self._label_y = "Y"
self._isometric_axis = True
self._auto_relim = True
self._autoscale = True
self._auto_relim_update = False
self._autoscale_update = False
self._highlight_data = None
self._highlight_data_update = False
self._current_data = None
self._current_data_update = False
super(PamhyrPlot, self).__init__(data=data) super(PamhyrPlot, self).__init__(data=data)
@property @property
@ -42,3 +82,102 @@ class PamhyrPlot(APlot):
@property @property
def toolbar(self): def toolbar(self):
return self._toolbar return self._toolbar
@property
def table(self):
return self._table
@property
def label_x(self):
return self._label_x
@label_x.setter
def label_x(self, name):
self._label_x = name
@property
def label_y(self):
return self._label_x
@label_y.setter
def label_y(self, name):
self._label_y = name
@property
def highlight(self):
return self._highlight_data
@highlight.setter
def highlight(self, data):
self._highlight_data = data
self._highlight_data_update = True
@property
def current(self):
return self._current_data
@current.setter
def current(self, data):
self._current_data = data
self._current_data_update = True
def init_axes(self):
self.canvas.axes.cla()
self.canvas.axes.grid(
color=self.color_axes_grid,
linestyle='--',
linewidth=0.5
)
self.init_axes_labels()
self.init_axes_axis()
def init_axes_labels(self):
self.canvas.axes.set_xlabel(
self._label_x,
color=self.color_axes_labels,
fontsize=10
)
self.canvas.axes.set_ylabel(
self._label_y,
color=self.color_axes_labels,
fontsize=10
)
def init_axes_axis(self):
if self._isometric_axis:
self.canvas.axes.axis("equal")
else:
self.canvas.axes.axis("tight")
def idle(self):
if self._auto_relim:
self.canvas.axes.relim()
if self._autoscale:
self.canvas.axes.autoscale_view(True, True, True)
self.canvas.axes.autoscale()
self.canvas.figure.tight_layout()
self.canvas.figure.canvas.draw_idle()
self.toolbar_update()
def update_idle(self):
if self._auto_relim_update:
self.canvas.axes.relim()
if self._autoscale_update:
self.canvas.axes.autoscale_view(True, True, True)
self.canvas.axes.autoscale()
self.canvas.figure.tight_layout()
self.canvas.figure.canvas.draw_idle()
self.toolbar_update()
def toolbar_update(self):
if self._toolbar is not None:
self._toolbar.update()

View File

@ -54,137 +54,173 @@ class PamhyrPlotToolbar(NavigationToolbar2QT):
(None, None, None, None), (None, None, None, None),
] ]
icons = [] self.icons = []
if "home" in items: if "home" in items:
self.toolitems.append( self.init_tool_home()
( self.add_tool_separator()
'Home',
_translate("Toolbar", 'Default view'),
'home', 'home'
)
)
self.toolitems.append((None, None, None, None))
if "back/forward" in items: if "back/forward" in items:
self.toolitems.append( self.init_tool_back_forward()
( self.add_tool_separator()
'Back',
_translate("Toolbar", 'Back to previous view'),
'back', 'back'
)
)
self.toolitems.append(('Forward', _translate(
"Toolbar", 'Return to next view'), 'forward', 'forward'))
self.toolitems.append((None, None, None, None))
if "move" in items: if "move" in items:
self.toolitems.append( self.init_tool_move()
('Pan', _translate( self.add_tool_separator()
"Toolbar",
'Axes panoramic'
), 'move', 'pan'))
self.toolitems.append((None, None, None, None))
if "zoom" in items: if "zoom" in items:
self.toolitems.append( self.init_tool_zoom()
( self.add_tool_separator()
'Zoom',
_translate("Toolbar", 'Zoom'),
'zoom_to_rect', 'zoom'
)
)
self.toolitems.append((None, None, None, None))
icon_zoom = QtGui.QIcon()
icon_zoom.addPixmap(QtGui.QPixmap(
os.path.abspath(f"{file_path}/../../ui/ressources/zoom.png")
))
icons.append(("zoom", icon_zoom))
if "iso" in items: if "iso" in items:
self.toolitems.append( self.init_tool_iso()
('Isometric_view', _translate( self.add_tool_separator()
"Toolbar", 'Isometric view (Shift+W)'
), '', 'isometric_view')
)
self.toolitems.append((None, None, None, None))
self.toolitems.append(
('GlobalView', _translate(
"Toolbar", 'Auto scale view (Shift+X)'
), '', 'non_isometric_view')
)
self.toolitems.append((None, None, None, None)),
icon_btn_isometric_view = QtGui.QIcon()
icon_btn_isometric_view.addPixmap(
QtGui.QPixmap(
os.path.abspath(
f"{file_path}/../../ui/ressources/zoom_fit_11.png"
)
)
)
icon_btn_global_view = QtGui.QIcon()
icon_btn_global_view.addPixmap(
QtGui.QPixmap(
os.path.abspath(
f"{file_path}/../../ui/ressources/zoom_fit.png"
)
)
)
icons.append(("isometric_view", icon_btn_isometric_view))
icons.append(("non_isometric_view", icon_btn_global_view))
if "save" in items: if "save" in items:
self.toolitems.append( self.init_tool_save()
('Save', _translate(
"Toolbar", 'Save the figure'
), 'filesave', 'save_figure')
)
self.toolitems.append((None, None, None, None))
NavigationToolbar2QT.__init__(self, canvas, parent) NavigationToolbar2QT.__init__(self, canvas, parent)
btn_size = QSize(40, 28) btn_size = QSize(40, 28)
actions = self.findChildren(QAction) actions = self.findChildren(QAction)
for a, i in icons: for a, i in self.icons:
self._actions[a].setIcon(i) self._actions[a].setIcon(i)
self.addSeparator() self.addSeparator()
def save_figure(self, *args): def add_tool_separator(self):
filetypes = self.canvas.get_supported_filetypes_grouped() self.toolitems.append((None, None, None, None))
sorted_filetypes = sorted(filetypes.items())
default_filetype = self.canvas.get_default_filetype()
def init_tool_home(self):
self.toolitems.append(
(
'Home',
_translate("Toolbar", 'Default view'),
'home', 'home'
)
)
def init_tool_back_forward(self):
self.toolitems.append(
(
'Back',
_translate("Toolbar", 'Back to previous view'),
'back', 'back'
)
)
self.toolitems.append(
(
'Forward',
_translate("Toolbar", 'Return to next view'),
'forward', 'forward'
)
)
def init_tool_move(self):
self.toolitems.append(
(
'Pan',
_translate("Toolbar", 'Axes panoramic'),
'move', 'pan'
)
)
def init_tool_zoom(self):
self.toolitems.append(
(
'Zoom',
_translate("Toolbar", 'Zoom'),
'zoom_to_rect', 'zoom'
)
)
icon_zoom = QtGui.QIcon()
icon_zoom.addPixmap(QtGui.QPixmap(
os.path.abspath(f"{file_path}/../../ui/ressources/zoom.png")
))
self.icons.append(("zoom", icon_zoom))
def init_tool_iso(self):
self.toolitems.append(
(
'Isometric_view',
_translate("Toolbar", 'Isometric view (Shift+W)'),
'', 'isometric_view'
)
)
self.toolitems.append(
(
'GlobalView',
_translate("Toolbar", 'Auto scale view (Shift+X)'),
'', 'non_isometric_view'
)
)
icon_btn_isometric_view = QtGui.QIcon()
icon_btn_isometric_view.addPixmap(
QtGui.QPixmap(
os.path.abspath(
f"{file_path}/../../ui/ressources/zoom_fit_11.png"
)
)
)
icon_btn_global_view = QtGui.QIcon()
icon_btn_global_view.addPixmap(
QtGui.QPixmap(
os.path.abspath(
f"{file_path}/../../ui/ressources/zoom_fit.png"
)
)
)
self.icons.append(("isometric_view", icon_btn_isometric_view))
self.icons.append(("non_isometric_view", icon_btn_global_view))
def init_tool_save(self):
self.toolitems.append(
(
'Save',
_translate("Toolbar", 'Save the figure'),
'filesave', 'save_figure'
)
)
def save_figure(self, *args):
file_types = self.canvas.get_supported_filetypes_grouped()
default_file_type = self.canvas.get_default_filetype()
start = os.path.join(
os.path.expanduser(mpl.rcParams['savefig.directory']),
self.canvas.get_default_filename()
)
startpath = os.path.expanduser(mpl.rcParams['savefig.directory'])
start = os.path.join(startpath, self.canvas.get_default_filename())
filters = [] filters = []
selectedFilter = None selected_filter = None
for name, exts in sorted_filetypes: for name in file_types:
exts_list = " ".join(['*.%s' % ext for ext in exts]) exts = file_types[name]
filter = '%s (%s)' % (name, exts_list) exts_list = " ".join([f"*.{ext}" for ext in exts])
if default_filetype in exts: new = f"{name} ({exts_list})"
selectedFilter = filter
filters.append(filter) if default_file_type in exts:
selected_filter = new
filters.append(new)
filters = ';;'.join(filters) filters = ';;'.join(filters)
fname, filter = qt_compat._getSaveFileName( file_name, _ = qt_compat._getSaveFileName(
self.canvas.parent(), self.canvas.parent(),
_translate("MainWindow_reach", "Select destination file"), _translate("MainWindow_reach", "Select destination file"),
start, start, filters,
filters, selectedFilter) selected_filter
)
if fname:
if startpath != "":
mpl.rcParams['savefig.directory'] = os.path.dirname(fname)
if file_name:
try: try:
self.canvas.figure.savefig(fname) self.canvas.figure.savefig(file_name)
except Exception as e: except Exception as e:
QtWidgets.QMessageBox.critical( QtWidgets.QMessageBox.critical(
self, "Error saving file", str(e), self, "Error saving file", str(e),