Skip to content

Commit be3ed98

Browse files
committed
Users can override the napari-theme-based style
... with their own custom stylesheet. At the moment this must be called 'user.mplstyle' in the cwd.
1 parent 3679731 commit be3ed98

File tree

1 file changed

+29
-6
lines changed

1 file changed

+29
-6
lines changed

src/napari_matplotlib/base.py

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
from pathlib import Path
33
from typing import List, Optional, Tuple
44

5+
import matplotlib.style
56
import napari
67
from matplotlib.axes import Axes
78
from matplotlib.backends.backend_qtagg import (
@@ -41,9 +42,11 @@ def __init__(
4142
super().__init__(parent=parent)
4243
self.viewer = napari_viewer
4344

45+
has_mpl_stylesheet = self._apply_user_stylesheet_if_present()
4446
self.canvas = FigureCanvas()
4547

46-
self.canvas.figure.patch.set_facecolor("none")
48+
if not has_mpl_stylesheet:
49+
self.canvas.figure.patch.set_facecolor("none")
4750
self.canvas.figure.set_layout_engine("constrained")
4851
self.toolbar = NapariNavigationToolbar(
4952
self.canvas, parent=self
@@ -70,10 +73,16 @@ def add_single_axes(self) -> None:
7073
The Axes is saved on the ``.axes`` attribute for later access.
7174
"""
7275
self.axes = self.figure.subplots()
73-
self.apply_napari_colorscheme(self.axes)
76+
self.apply_style(self.axes)
77+
78+
def apply_style(self, ax: Axes) -> None:
79+
"""
80+
Use the user-supplied stylesheet if present, otherwise apply the
81+
napari-compatible colorscheme (theme-dependent) to an Axes.
82+
"""
83+
if self._apply_user_stylesheet_if_present():
84+
return
7485

75-
def apply_napari_colorscheme(self, ax: Axes) -> None:
76-
"""Apply napari-compatible colorscheme to an Axes."""
7786
# get the foreground colours from current theme
7887
theme = napari.utils.theme.get_theme(self.viewer.theme, as_dict=False)
7988
fg_colour = theme.foreground.as_hex() # fg is a muted contrast to bg
@@ -93,6 +102,20 @@ def apply_napari_colorscheme(self, ax: Axes) -> None:
93102
ax.tick_params(axis="x", colors=text_colour)
94103
ax.tick_params(axis="y", colors=text_colour)
95104

105+
def _apply_user_stylesheet_if_present(self) -> bool:
106+
"""
107+
Apply the user-supplied stylesheet if present.
108+
109+
Returns
110+
-------
111+
True if the stylesheet was present and applied.
112+
False otherwise.
113+
"""
114+
if (Path.cwd() / "user.mplstyle").exists():
115+
matplotlib.style.use("./user.mplstyle")
116+
return True
117+
return False
118+
96119
def _on_theme_change(self) -> None:
97120
"""Update MPL toolbar and axis styling when `napari.Viewer.theme` is changed.
98121
@@ -101,7 +124,7 @@ def _on_theme_change(self) -> None:
101124
"""
102125
self._replace_toolbar_icons()
103126
if self.figure.gca():
104-
self.apply_napari_colorscheme(self.figure.gca())
127+
self.apply_style(self.figure.gca())
105128

106129
def _theme_has_light_bg(self) -> bool:
107130
"""
@@ -245,7 +268,7 @@ def _draw(self) -> None:
245268
isinstance(layer, self.input_layer_types) for layer in self.layers
246269
):
247270
self.draw()
248-
self.apply_napari_colorscheme(self.figure.gca())
271+
self.apply_style(self.figure.gca())
249272
self.canvas.draw()
250273

251274
def clear(self) -> None:

0 commit comments

Comments
 (0)