From cd4119caecd09e34289aa37fb250a88258cef3c9 Mon Sep 17 00:00:00 2001 From: Patrick Shriwise Date: Sun, 15 Feb 2026 07:41:57 -0600 Subject: [PATCH 1/3] Add a diaglog box for setting font sizes of axis and tick labels in the plot --- openmc_plotter/main_window.py | 36 ++++++- openmc_plotter/plotgui.py | 172 +++++++++++++++++++++++++++++++++- openmc_plotter/plotmodel.py | 46 +++++++++ 3 files changed, 249 insertions(+), 5 deletions(-) diff --git a/openmc_plotter/main_window.py b/openmc_plotter/main_window.py index 2ae8e20..3efa4ef 100755 --- a/openmc_plotter/main_window.py +++ b/openmc_plotter/main_window.py @@ -21,7 +21,7 @@ _HAVE_VTK = False from .plotmodel import PlotModel, DomainTableModel, hash_model -from .plotgui import PlotImage, ColorDialog +from .plotgui import PlotImage, ColorDialog, AppearanceDialog from .docks import TabbedDock from .overlays import ShortcutsOverlay from .tools import ExportDataDialog, SourceSitesDialog @@ -96,6 +96,10 @@ def loadGui(self, use_settings_pkl=True): self.colorDialog = ColorDialog(self.model, self.font_metric, self) self.colorDialog.hide() + # Appearance Dialog + self.appearanceDialog = AppearanceDialog(self.model, self.font_metric, self) + self.appearanceDialog.hide() + # Tools self.exportDataDialog = ExportDataDialog(self.model, self.font_metric, self) self.sourceSitesDialog = SourceSitesDialog(self.model, self.font_metric, self) @@ -127,6 +131,7 @@ def loadGui(self, use_settings_pkl=True): self.geometryPanel.update() self.tallyPanel.update() self.colorDialog.updateDialogValues() + self.appearanceDialog.updateDialogValues() QtCore.QTimer.singleShot(0, self.requestPlotUpdate) @@ -254,6 +259,11 @@ def createMenuBar(self): self.restoreAction.setStatusTip('Restore to default plot view') self.restoreAction.triggered.connect(self.restoreDefault) + self.appearanceAction = QAction("Appearance...", self) + self.appearanceAction.setToolTip('Edit plot font sizes') + self.appearanceAction.setStatusTip('Edit plot font sizes') + self.appearanceAction.triggered.connect(self.showAppearanceDialog) + self.editMenu = self.mainMenu.addMenu('&Edit') self.editMenu.addAction(self.applyAction) self.editMenu.addSeparator() @@ -262,6 +272,8 @@ def createMenuBar(self): self.editMenu.addSeparator() self.editMenu.addAction(self.restoreAction) self.editMenu.addSeparator() + self.editMenu.addAction(self.appearanceAction) + self.editMenu.addSeparator() self.editMenu.aboutToShow.connect(self.updateEditMenu) # Edit -> Basis Menu @@ -551,6 +563,7 @@ def loadViewFile(self, filename): self.model.activeView.outlinesMat = False self.geometryPanel.update() self.colorDialog.updateDialogValues() + self.appearanceDialog.updateDialogValues() self.applyChanges() message = '{} loaded'.format(filename) else: @@ -663,6 +676,7 @@ def undo(self): self.model.undo() self.geometryPanel.update() self.colorDialog.updateDialogValues() + self.appearanceDialog.updateDialogValues() self.requestPlotUpdate() if not self.model.previousViews: @@ -675,6 +689,7 @@ def redo(self): self.model.redo() self.geometryPanel.update() self.colorDialog.updateDialogValues() + self.appearanceDialog.updateDialogValues() self.requestPlotUpdate() if not self.model.subsequentViews: @@ -687,6 +702,7 @@ def restoreDefault(self): self.model.activeView.adopt_plotbase(self.model.defaultView) self.geometryPanel.update() self.colorDialog.updateDialogValues() + self.appearanceDialog.updateDialogValues() self.requestPlotUpdate() self.model.subsequentViews = [] @@ -819,6 +835,11 @@ def showColorDialog(self): self.colorDialog.raise_() self.colorDialog.activateWindow() + def showAppearanceDialog(self): + self.appearanceDialog.show() + self.appearanceDialog.raise_() + self.appearanceDialog.activateWindow() + def showExportDialog(self): self.exportDataDialog.show() self.exportDataDialog.raise_() @@ -931,6 +952,19 @@ def resetColors(self): self.colorDialog.updateDialogValues() self.applyChanges() + # Appearance dialog methods + def editAxisLabelFontSize(self, value): + self.model.activeView.axisLabelSize = int(value) + + def editAxisTickFontSize(self, value): + self.model.activeView.axisTickSize = int(value) + + def editColorbarLabelFontSize(self, value): + self.model.activeView.colorbarLabelSize = int(value) + + def editColorbarTickFontSize(self, value): + self.model.activeView.colorbarTickSize = int(value) + # Tally dock methods def editSelectedTally(self, event): diff --git a/openmc_plotter/plotgui.py b/openmc_plotter/plotgui.py index b04b1b6..73d2650 100644 --- a/openmc_plotter/plotgui.py +++ b/openmc_plotter/plotgui.py @@ -9,6 +9,8 @@ from matplotlib.figure import Figure from matplotlib import lines as mlines from matplotlib.colors import SymLogNorm +from matplotlib.font_manager import FontProperties +from matplotlib.textpath import TextPath from matplotlib.backends.backend_qt5agg import FigureCanvas import matplotlib.pyplot as plt import numpy as np @@ -180,6 +182,60 @@ def saveImage(self, filename): filename += ".png" self.figure.savefig(filename, transparent=True) + def _colorbar_tick_texts(self, colorbar): + labels = [t.get_text() for t in colorbar.ax.get_yticklabels()] + labels = [t for t in labels if t] + if labels: + return labels + try: + formatter = colorbar.ax.yaxis.get_major_formatter() + locs = colorbar.get_ticks() + return [t for t in formatter.format_ticks(locs) if t] + except Exception: + return [] + + def _text_width_pts(self, text, size): + if not text: + return 0.0 + try: + path = TextPath((0, 0), text, prop=FontProperties(size=size)) + return path.get_extents().width + except Exception: + return 0.6 * size * len(text) + + def _text_height_pts(self, text, size): + if not text: + return float(size) + try: + path = TextPath((0, 0), text, prop=FontProperties(size=size)) + return path.get_extents().height + except Exception: + return float(size) + + def _colorbar_tick_pad(self, colorbar): + ticks = colorbar.ax.yaxis.get_major_ticks() + if ticks: + try: + return float(ticks[0].get_pad()) + except Exception: + pass + try: + return float(plt.rcParams.get("ytick.major.pad", 4)) + except Exception: + return 4.0 + + def _colorbar_label_pad(self, colorbar, label_text, label_size, tick_size): + # Estimate a label pad that grows with tick label width + # to avoid label/tick overlap when fonts are enlarged. + tick_texts = self._colorbar_tick_texts(colorbar) + max_tick_width = 0.0 + for text in tick_texts: + max_tick_width = max(max_tick_width, + self._text_width_pts(text, tick_size)) + label_height = self._text_height_pts(label_text, label_size) + tick_pad = self._colorbar_tick_pad(colorbar) + return max(15.0, max_tick_width + 0.5 * label_height + tick_pad + 2.0) + def getDataIndices(self, event): cv = self.model.currentView @@ -543,6 +599,10 @@ def updatePixmap(self): self.figure.clear() cv = self.model.currentView + axis_label_size = cv.axisLabelSize + axis_tick_size = cv.axisTickSize + colorbar_label_size = cv.colorbarLabelSize + colorbar_tick_size = cv.colorbarTickSize # set figure bg color to match window window_bg = self.parent.palette().color(QtGui.QPalette.Window) self.figure.patch.set_facecolor(rgb_normalize(window_bg.getRgb())) @@ -589,9 +649,15 @@ def updatePixmap(self): # add colorbar self.property_colorbar = self.figure.colorbar(self.image, anchor=(1.0, 0.0)) + self.property_colorbar.ax.tick_params(labelsize=colorbar_tick_size) + labelpad = self._colorbar_label_pad(self.property_colorbar, + cmap_label, + colorbar_label_size, + colorbar_tick_size) self.property_colorbar.set_label(cmap_label, rotation=-90, - labelpad=15) + labelpad=labelpad, + fontsize=colorbar_label_size) # draw line on colorbar dl = self.property_colorbar.ax.dataLim.get_points() self.data_indicator = mlines.Line2D(dl[:][0], @@ -610,8 +676,11 @@ def updatePixmap(self): # set axis labels axis_label_str = "{} (cm)" - self.ax.set_xlabel(axis_label_str.format(cv.basis[0])) - self.ax.set_ylabel(axis_label_str.format(cv.basis[1])) + self.ax.set_xlabel(axis_label_str.format(cv.basis[0]), + fontsize=axis_label_size) + self.ax.set_ylabel(axis_label_str.format(cv.basis[1]), + fontsize=axis_label_size) + self.ax.tick_params(axis='both', labelsize=axis_tick_size) # generate tally image image_data, extents, data_min, data_max, units = self.model.create_tally_image() @@ -715,9 +784,15 @@ def updatePixmap(self): self.main_window.updateTallyMinMax() self.tally_colorbar.mappable.set_clim(data_min, data_max) + self.tally_colorbar.ax.tick_params(labelsize=colorbar_tick_size) + labelpad = self._colorbar_label_pad(self.tally_colorbar, + units, + colorbar_label_size, + colorbar_tick_size) self.tally_colorbar.set_label(units, rotation=-90, - labelpad=15) + labelpad=labelpad, + fontsize=colorbar_label_size) # annotate outlines self.add_outlines() @@ -1318,3 +1393,92 @@ def updateUniverseLevel(self): def updateDomainTabs(self): self.cellTable.setModel(self.main_window.cellsModel) self.matTable.setModel(self.main_window.materialsModel) + + +class AppearanceDialog(QDialog): + + def __init__(self, model, font_metric, parent=None): + super().__init__(parent) + + self.setWindowTitle('Appearance') + + self.model = model + self.font_metric = font_metric + self.main_window = parent + + self.createDialogLayout() + + def createDialogLayout(self): + self.axisLabelSizeBox = QSpinBox() + self.axisLabelSizeBox.setRange(1, 96) + self.axisLabelSizeBox.setSuffix(" pt") + self.axisLabelSizeBox.valueChanged.connect( + self.main_window.editAxisLabelFontSize) + + self.axisTickSizeBox = QSpinBox() + self.axisTickSizeBox.setRange(1, 96) + self.axisTickSizeBox.setSuffix(" pt") + self.axisTickSizeBox.valueChanged.connect( + self.main_window.editAxisTickFontSize) + + self.colorbarLabelSizeBox = QSpinBox() + self.colorbarLabelSizeBox.setRange(1, 96) + self.colorbarLabelSizeBox.setSuffix(" pt") + self.colorbarLabelSizeBox.valueChanged.connect( + self.main_window.editColorbarLabelFontSize) + + self.colorbarTickSizeBox = QSpinBox() + self.colorbarTickSizeBox.setRange(1, 96) + self.colorbarTickSizeBox.setSuffix(" pt") + self.colorbarTickSizeBox.valueChanged.connect( + self.main_window.editColorbarTickFontSize) + + formLayout = QFormLayout() + formLayout.setAlignment(QtCore.Qt.AlignHCenter) + formLayout.setFormAlignment(QtCore.Qt.AlignHCenter) + formLayout.setLabelAlignment(QtCore.Qt.AlignLeft) + formLayout.addRow('Axis Labels:', self.axisLabelSizeBox) + formLayout.addRow('Axis Ticks:', self.axisTickSizeBox) + formLayout.addRow(HorizontalLine()) + formLayout.addRow('Colorbar Labels:', self.colorbarLabelSizeBox) + formLayout.addRow('Colorbar Ticks:', self.colorbarTickSizeBox) + + self.createButtonBox() + + layout = QVBoxLayout() + layout.addLayout(formLayout) + layout.addWidget(self.buttonBox) + self.setLayout(layout) + + def createButtonBox(self): + applyButton = QPushButton("Apply Changes") + applyButton.clicked.connect(self.main_window.applyChanges) + closeButton = QPushButton("Close") + closeButton.clicked.connect(self.hide) + + buttonLayout = QHBoxLayout() + buttonLayout.addStretch(1) + buttonLayout.addWidget(applyButton) + buttonLayout.addWidget(closeButton) + + self.buttonBox = QWidget() + self.buttonBox.setLayout(buttonLayout) + + def updateDialogValues(self): + av = self.model.activeView + boxes = ( + self.axisLabelSizeBox, + self.axisTickSizeBox, + self.colorbarLabelSizeBox, + self.colorbarTickSizeBox, + ) + for box in boxes: + box.blockSignals(True) + + self.axisLabelSizeBox.setValue(av.axisLabelSize) + self.axisTickSizeBox.setValue(av.axisTickSize) + self.colorbarLabelSizeBox.setValue(av.colorbarLabelSize) + self.colorbarTickSizeBox.setValue(av.colorbarTickSize) + + for box in boxes: + box.blockSignals(False) diff --git a/openmc_plotter/plotmodel.py b/openmc_plotter/plotmodel.py index a339fd2..0549524 100644 --- a/openmc_plotter/plotmodel.py +++ b/openmc_plotter/plotmodel.py @@ -21,6 +21,30 @@ from .statepointmodel import StatePointModel from .plot_colors import random_rgb + +def _resolve_font_size(value, fallback): + try: + from matplotlib.font_manager import FontProperties + return int(round(FontProperties(size=value).get_size_in_points())) + except Exception: + return fallback + + +def _default_font_sizes(): + try: + from matplotlib import rcParams + axis_label = _resolve_font_size(rcParams.get("axes.labelsize", 10), 10) + axis_tick = _resolve_font_size(rcParams.get("xtick.labelsize", 10), 10) + colorbar_label = _resolve_font_size(rcParams.get("axes.labelsize", axis_label), axis_label) + colorbar_tick = _resolve_font_size(rcParams.get("ytick.labelsize", axis_tick), axis_tick) + return axis_label, axis_tick, colorbar_label, colorbar_tick + except Exception: + return (10, 10, 10, 10) + + +_DEFAULT_AXIS_LABEL_SIZE, _DEFAULT_AXIS_TICK_SIZE, \ + _DEFAULT_COLORBAR_LABEL_SIZE, _DEFAULT_COLORBAR_TICK_SIZE = _default_font_sizes() + ID, NAME, COLOR, COLORLABEL, MASK, HIGHLIGHT = range(6) _VOID_REGION = -1 @@ -1113,6 +1137,14 @@ class PlotViewIndependent: Indicates whether or not tallies are displayed as contours tallyContourLevels : str Number of contours levels or explicit level values + axisLabelSize : int + Font size for axis labels + axisTickSize : int + Font size for axis tick labels + colorbarLabelSize : int + Font size for colorbar labels + colorbarTickSize : int + Font size for colorbar tick labels """ def __init__(self): @@ -1157,6 +1189,12 @@ def __init__(self): self.tallyContours = False self.tallyContourLevels = "" + # Plot text sizing + self.axisLabelSize = _DEFAULT_AXIS_LABEL_SIZE + self.axisTickSize = _DEFAULT_AXIS_TICK_SIZE + self.colorbarLabelSize = _DEFAULT_COLORBAR_LABEL_SIZE + self.colorbarTickSize = _DEFAULT_COLORBAR_TICK_SIZE + def __setstate__(self, state): """Handle backward compatibility when unpickling old views""" self.__dict__.update(state) @@ -1173,6 +1211,14 @@ def __setstate__(self, state): self.tallyDataMinMaxType = 'full' # Remove old attributes if present self.__dict__.pop('tallyDataUserMinMax', None) + if not hasattr(self, 'axisLabelSize'): + self.axisLabelSize = _DEFAULT_AXIS_LABEL_SIZE + if not hasattr(self, 'axisTickSize'): + self.axisTickSize = _DEFAULT_AXIS_TICK_SIZE + if not hasattr(self, 'colorbarLabelSize'): + self.colorbarLabelSize = _DEFAULT_COLORBAR_LABEL_SIZE + if not hasattr(self, 'colorbarTickSize'): + self.colorbarTickSize = _DEFAULT_COLORBAR_TICK_SIZE def getDataLimits(self): return self.data_minmax From e8a54eb9faae66a22436fad6f0e5009ce59136cf Mon Sep 17 00:00:00 2001 From: Patrick Shriwise Date: Sun, 15 Feb 2026 08:04:24 -0600 Subject: [PATCH 2/3] Removing superfluous close button and adjusting layout --- openmc_plotter/plotgui.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/openmc_plotter/plotgui.py b/openmc_plotter/plotgui.py index 73d2650..7adc62b 100644 --- a/openmc_plotter/plotgui.py +++ b/openmc_plotter/plotgui.py @@ -1453,13 +1453,10 @@ def createDialogLayout(self): def createButtonBox(self): applyButton = QPushButton("Apply Changes") applyButton.clicked.connect(self.main_window.applyChanges) - closeButton = QPushButton("Close") - closeButton.clicked.connect(self.hide) + applyButton.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred) buttonLayout = QHBoxLayout() - buttonLayout.addStretch(1) - buttonLayout.addWidget(applyButton) - buttonLayout.addWidget(closeButton) + buttonLayout.addWidget(applyButton, 1) self.buttonBox = QWidget() self.buttonBox.setLayout(buttonLayout) From f29bbd41ab3e15b49ca1efd6b467e838d1f6ad44 Mon Sep 17 00:00:00 2001 From: Patrick Shriwise Date: Sun, 15 Feb 2026 08:28:06 -0600 Subject: [PATCH 3/3] Add font options for axis and colorbar labels and ticks --- openmc_plotter/main_window.py | 12 +++ openmc_plotter/plotgui.py | 169 +++++++++++++++++++++++++++++----- openmc_plotter/plotmodel.py | 20 ++++ 3 files changed, 179 insertions(+), 22 deletions(-) diff --git a/openmc_plotter/main_window.py b/openmc_plotter/main_window.py index 3efa4ef..4ea9a74 100755 --- a/openmc_plotter/main_window.py +++ b/openmc_plotter/main_window.py @@ -965,6 +965,18 @@ def editColorbarLabelFontSize(self, value): def editColorbarTickFontSize(self, value): self.model.activeView.colorbarTickSize = int(value) + def editAxisLabelFont(self, value): + self.model.activeView.axisLabelFont = value or None + + def editAxisTickFont(self, value): + self.model.activeView.axisTickFont = value or None + + def editColorbarLabelFont(self, value): + self.model.activeView.colorbarLabelFont = value or None + + def editColorbarTickFont(self, value): + self.model.activeView.colorbarTickFont = value or None + # Tally dock methods def editSelectedTally(self, event): diff --git a/openmc_plotter/plotgui.py b/openmc_plotter/plotgui.py index 7adc62b..1a5827e 100644 --- a/openmc_plotter/plotgui.py +++ b/openmc_plotter/plotgui.py @@ -5,9 +5,10 @@ QFormLayout, QComboBox, QSpinBox, QLabel, QDoubleSpinBox, QSizePolicy, QMessageBox, QCheckBox, QRubberBand, QMenu, QDialog, - QTabWidget, QTableView, QHeaderView) + QTabWidget, QTableView, QHeaderView, QListView) from matplotlib.figure import Figure from matplotlib import lines as mlines +from matplotlib import font_manager from matplotlib.colors import SymLogNorm from matplotlib.font_manager import FontProperties from matplotlib.textpath import TextPath @@ -22,6 +23,38 @@ from .scientific_spin_box import ScientificDoubleSpinBox from .custom_widgets import HorizontalLine +_DEFAULT_FONT_LABEL = "Default (Matplotlib)" +_FONT_FAMILY_CACHE = None + + +def _matplotlib_font_names(): + global _FONT_FAMILY_CACHE + if _FONT_FAMILY_CACHE is not None: + return _FONT_FAMILY_CACHE + names = set() + try: + for entry in font_manager.fontManager.ttflist: + name = getattr(entry, "name", None) + if name: + names.add(name) + except Exception: + names = set() + _FONT_FAMILY_CACHE = sorted(names, key=lambda s: s.lower()) + return _FONT_FAMILY_CACHE + + +def _build_font_combo(): + combo = QComboBox() + combo.setEditable(False) + combo.setMaxVisibleItems(20) + view = QListView() + view.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded) + combo.setView(view) + combo.addItem(_DEFAULT_FONT_LABEL, None) + for name in _matplotlib_font_names(): + combo.addItem(name, name) + return combo + class PlotUpdateOverlay(QWidget): @@ -194,20 +227,28 @@ def _colorbar_tick_texts(self, colorbar): except Exception: return [] - def _text_width_pts(self, text, size): + def _text_width_pts(self, text, size, font_name=None): if not text: return 0.0 try: - path = TextPath((0, 0), text, prop=FontProperties(size=size)) + if font_name: + prop = FontProperties(size=size, family=font_name) + else: + prop = FontProperties(size=size) + path = TextPath((0, 0), text, prop=prop) return path.get_extents().width except Exception: return 0.6 * size * len(text) - def _text_height_pts(self, text, size): + def _text_height_pts(self, text, size, font_name=None): if not text: return float(size) try: - path = TextPath((0, 0), text, prop=FontProperties(size=size)) + if font_name: + prop = FontProperties(size=size, family=font_name) + else: + prop = FontProperties(size=size) + path = TextPath((0, 0), text, prop=prop) return path.get_extents().height except Exception: return float(size) @@ -224,15 +265,16 @@ def _colorbar_tick_pad(self, colorbar): except Exception: return 4.0 - def _colorbar_label_pad(self, colorbar, label_text, label_size, tick_size): + def _colorbar_label_pad(self, colorbar, label_text, label_size, tick_size, + label_font=None, tick_font=None): # Estimate a label pad that grows with tick label width # to avoid label/tick overlap when fonts are enlarged. tick_texts = self._colorbar_tick_texts(colorbar) max_tick_width = 0.0 for text in tick_texts: max_tick_width = max(max_tick_width, - self._text_width_pts(text, tick_size)) - label_height = self._text_height_pts(label_text, label_size) + self._text_width_pts(text, tick_size, tick_font)) + label_height = self._text_height_pts(label_text, label_size, label_font) tick_pad = self._colorbar_tick_pad(colorbar) return max(15.0, max_tick_width + 0.5 * label_height + tick_pad + 2.0) @@ -603,6 +645,10 @@ def updatePixmap(self): axis_tick_size = cv.axisTickSize colorbar_label_size = cv.colorbarLabelSize colorbar_tick_size = cv.colorbarTickSize + axis_label_font = cv.axisLabelFont + axis_tick_font = cv.axisTickFont + colorbar_label_font = cv.colorbarLabelFont + colorbar_tick_font = cv.colorbarTickFont # set figure bg color to match window window_bg = self.parent.palette().color(QtGui.QPalette.Window) self.figure.patch.set_facecolor(rgb_normalize(window_bg.getRgb())) @@ -650,14 +696,27 @@ def updatePixmap(self): self.property_colorbar = self.figure.colorbar(self.image, anchor=(1.0, 0.0)) self.property_colorbar.ax.tick_params(labelsize=colorbar_tick_size) + if colorbar_tick_font: + for label in self.property_colorbar.ax.get_yticklabels(): + label.set_fontname(colorbar_tick_font) labelpad = self._colorbar_label_pad(self.property_colorbar, cmap_label, colorbar_label_size, - colorbar_tick_size) - self.property_colorbar.set_label(cmap_label, - rotation=-90, - labelpad=labelpad, - fontsize=colorbar_label_size) + colorbar_tick_size, + label_font=colorbar_label_font, + tick_font=colorbar_tick_font) + if colorbar_label_font: + label_prop = FontProperties(family=colorbar_label_font) + self.property_colorbar.set_label(cmap_label, + rotation=-90, + labelpad=labelpad, + fontsize=colorbar_label_size, + fontproperties=label_prop) + else: + self.property_colorbar.set_label(cmap_label, + rotation=-90, + labelpad=labelpad, + fontsize=colorbar_label_size) # draw line on colorbar dl = self.property_colorbar.ax.dataLim.get_points() self.data_indicator = mlines.Line2D(dl[:][0], @@ -676,11 +735,23 @@ def updatePixmap(self): # set axis labels axis_label_str = "{} (cm)" - self.ax.set_xlabel(axis_label_str.format(cv.basis[0]), - fontsize=axis_label_size) - self.ax.set_ylabel(axis_label_str.format(cv.basis[1]), - fontsize=axis_label_size) + if axis_label_font: + axis_label_prop = FontProperties(family=axis_label_font) + self.ax.set_xlabel(axis_label_str.format(cv.basis[0]), + fontsize=axis_label_size, + fontproperties=axis_label_prop) + self.ax.set_ylabel(axis_label_str.format(cv.basis[1]), + fontsize=axis_label_size, + fontproperties=axis_label_prop) + else: + self.ax.set_xlabel(axis_label_str.format(cv.basis[0]), + fontsize=axis_label_size) + self.ax.set_ylabel(axis_label_str.format(cv.basis[1]), + fontsize=axis_label_size) self.ax.tick_params(axis='both', labelsize=axis_tick_size) + if axis_tick_font: + for label in self.ax.get_xticklabels() + self.ax.get_yticklabels(): + label.set_fontname(axis_tick_font) # generate tally image image_data, extents, data_min, data_max, units = self.model.create_tally_image() @@ -785,14 +856,27 @@ def updatePixmap(self): self.tally_colorbar.mappable.set_clim(data_min, data_max) self.tally_colorbar.ax.tick_params(labelsize=colorbar_tick_size) + if colorbar_tick_font: + for label in self.tally_colorbar.ax.get_yticklabels(): + label.set_fontname(colorbar_tick_font) labelpad = self._colorbar_label_pad(self.tally_colorbar, units, colorbar_label_size, - colorbar_tick_size) - self.tally_colorbar.set_label(units, - rotation=-90, - labelpad=labelpad, - fontsize=colorbar_label_size) + colorbar_tick_size, + label_font=colorbar_label_font, + tick_font=colorbar_tick_font) + if colorbar_label_font: + label_prop = FontProperties(family=colorbar_label_font) + self.tally_colorbar.set_label(units, + rotation=-90, + labelpad=labelpad, + fontsize=colorbar_label_size, + fontproperties=label_prop) + else: + self.tally_colorbar.set_label(units, + rotation=-90, + labelpad=labelpad, + fontsize=colorbar_label_size) # annotate outlines self.add_outlines() @@ -1433,15 +1517,39 @@ def createDialogLayout(self): self.colorbarTickSizeBox.valueChanged.connect( self.main_window.editColorbarTickFontSize) + self.axisLabelFontBox = _build_font_combo() + self.axisLabelFontBox.currentIndexChanged.connect( + lambda _: self.main_window.editAxisLabelFont( + self.axisLabelFontBox.currentData())) + + self.axisTickFontBox = _build_font_combo() + self.axisTickFontBox.currentIndexChanged.connect( + lambda _: self.main_window.editAxisTickFont( + self.axisTickFontBox.currentData())) + + self.colorbarLabelFontBox = _build_font_combo() + self.colorbarLabelFontBox.currentIndexChanged.connect( + lambda _: self.main_window.editColorbarLabelFont( + self.colorbarLabelFontBox.currentData())) + + self.colorbarTickFontBox = _build_font_combo() + self.colorbarTickFontBox.currentIndexChanged.connect( + lambda _: self.main_window.editColorbarTickFont( + self.colorbarTickFontBox.currentData())) + formLayout = QFormLayout() formLayout.setAlignment(QtCore.Qt.AlignHCenter) formLayout.setFormAlignment(QtCore.Qt.AlignHCenter) formLayout.setLabelAlignment(QtCore.Qt.AlignLeft) formLayout.addRow('Axis Labels:', self.axisLabelSizeBox) + formLayout.addRow('Axis Label Font:', self.axisLabelFontBox) formLayout.addRow('Axis Ticks:', self.axisTickSizeBox) + formLayout.addRow('Axis Tick Font:', self.axisTickFontBox) formLayout.addRow(HorizontalLine()) formLayout.addRow('Colorbar Labels:', self.colorbarLabelSizeBox) + formLayout.addRow('Colorbar Label Font:', self.colorbarLabelFontBox) formLayout.addRow('Colorbar Ticks:', self.colorbarTickSizeBox) + formLayout.addRow('Colorbar Tick Font:', self.colorbarTickFontBox) self.createButtonBox() @@ -1468,6 +1576,10 @@ def updateDialogValues(self): self.axisTickSizeBox, self.colorbarLabelSizeBox, self.colorbarTickSizeBox, + self.axisLabelFontBox, + self.axisTickFontBox, + self.colorbarLabelFontBox, + self.colorbarTickFontBox, ) for box in boxes: box.blockSignals(True) @@ -1476,6 +1588,19 @@ def updateDialogValues(self): self.axisTickSizeBox.setValue(av.axisTickSize) self.colorbarLabelSizeBox.setValue(av.colorbarLabelSize) self.colorbarTickSizeBox.setValue(av.colorbarTickSize) + av.axisLabelFont = self._set_font_box(self.axisLabelFontBox, av.axisLabelFont) + av.axisTickFont = self._set_font_box(self.axisTickFontBox, av.axisTickFont) + av.colorbarLabelFont = self._set_font_box(self.colorbarLabelFontBox, av.colorbarLabelFont) + av.colorbarTickFont = self._set_font_box(self.colorbarTickFontBox, av.colorbarTickFont) for box in boxes: box.blockSignals(False) + + def _set_font_box(self, box, value): + idx = box.findData(value) + if idx < 0: + idx = box.findData(None) + if idx < 0: + idx = 0 + box.setCurrentIndex(idx) + return box.currentData() diff --git a/openmc_plotter/plotmodel.py b/openmc_plotter/plotmodel.py index 0549524..8638518 100644 --- a/openmc_plotter/plotmodel.py +++ b/openmc_plotter/plotmodel.py @@ -1145,6 +1145,14 @@ class PlotViewIndependent: Font size for colorbar labels colorbarTickSize : int Font size for colorbar tick labels + axisLabelFont : str or None + Font family for axis labels + axisTickFont : str or None + Font family for axis tick labels + colorbarLabelFont : str or None + Font family for colorbar labels + colorbarTickFont : str or None + Font family for colorbar tick labels """ def __init__(self): @@ -1194,6 +1202,10 @@ def __init__(self): self.axisTickSize = _DEFAULT_AXIS_TICK_SIZE self.colorbarLabelSize = _DEFAULT_COLORBAR_LABEL_SIZE self.colorbarTickSize = _DEFAULT_COLORBAR_TICK_SIZE + self.axisLabelFont = None + self.axisTickFont = None + self.colorbarLabelFont = None + self.colorbarTickFont = None def __setstate__(self, state): """Handle backward compatibility when unpickling old views""" @@ -1219,6 +1231,14 @@ def __setstate__(self, state): self.colorbarLabelSize = _DEFAULT_COLORBAR_LABEL_SIZE if not hasattr(self, 'colorbarTickSize'): self.colorbarTickSize = _DEFAULT_COLORBAR_TICK_SIZE + if not hasattr(self, 'axisLabelFont'): + self.axisLabelFont = None + if not hasattr(self, 'axisTickFont'): + self.axisTickFont = None + if not hasattr(self, 'colorbarLabelFont'): + self.colorbarLabelFont = None + if not hasattr(self, 'colorbarTickFont'): + self.colorbarTickFont = None def getDataLimits(self): return self.data_minmax