2
2
from pathlib import Path
3
3
from typing import List , Optional , Tuple
4
4
5
+ import matplotlib .style
5
6
import napari
6
7
from matplotlib .axes import Axes
7
8
from matplotlib .backends .backend_qtagg import (
@@ -41,9 +42,11 @@ def __init__(
41
42
super ().__init__ (parent = parent )
42
43
self .viewer = napari_viewer
43
44
45
+ has_mpl_stylesheet = self ._apply_user_stylesheet_if_present ()
44
46
self .canvas = FigureCanvas ()
45
47
46
- self .canvas .figure .patch .set_facecolor ("none" )
48
+ if not has_mpl_stylesheet :
49
+ self .canvas .figure .patch .set_facecolor ("none" )
47
50
self .canvas .figure .set_layout_engine ("constrained" )
48
51
self .toolbar = NapariNavigationToolbar (
49
52
self .canvas , parent = self
@@ -70,10 +73,16 @@ def add_single_axes(self) -> None:
70
73
The Axes is saved on the ``.axes`` attribute for later access.
71
74
"""
72
75
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
74
85
75
- def apply_napari_colorscheme (self , ax : Axes ) -> None :
76
- """Apply napari-compatible colorscheme to an Axes."""
77
86
# get the foreground colours from current theme
78
87
theme = napari .utils .theme .get_theme (self .viewer .theme , as_dict = False )
79
88
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:
93
102
ax .tick_params (axis = "x" , colors = text_colour )
94
103
ax .tick_params (axis = "y" , colors = text_colour )
95
104
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
+
96
119
def _on_theme_change (self ) -> None :
97
120
"""Update MPL toolbar and axis styling when `napari.Viewer.theme` is changed.
98
121
@@ -101,7 +124,7 @@ def _on_theme_change(self) -> None:
101
124
"""
102
125
self ._replace_toolbar_icons ()
103
126
if self .figure .gca ():
104
- self .apply_napari_colorscheme (self .figure .gca ())
127
+ self .apply_style (self .figure .gca ())
105
128
106
129
def _theme_has_light_bg (self ) -> bool :
107
130
"""
@@ -245,7 +268,7 @@ def _draw(self) -> None:
245
268
isinstance (layer , self .input_layer_types ) for layer in self .layers
246
269
):
247
270
self .draw ()
248
- self .apply_napari_colorscheme (self .figure .gca ())
271
+ self .apply_style (self .figure .gca ())
249
272
self .canvas .draw ()
250
273
251
274
def clear (self ) -> None :
0 commit comments