Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 13d2268

Browse filesBrowse files
committed
Add support for custom style sheets
1 parent 669cdc2 commit 13d2268
Copy full SHA for 13d2268

File tree

3 files changed

+46
-21
lines changed
Filter options

3 files changed

+46
-21
lines changed

‎docs/user_guide.rst

Copy file name to clipboardExpand all lines: docs/user_guide.rst
+11Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,14 @@ To use these:
3636
1. Open the desired widget using the ``Plugins > napari-matplotlib`` menu in napari.
3737
2. Select a single layer that has a features table using the napari layers list in the bottom left-hand side of the window.
3838
3. Use the drop down menu(s) under the Matplotlib figure to select the feature(s) to plot.
39+
40+
Customising plots
41+
-----------------
42+
`Matplotlib style sheets <https://matplotlib.org/stable/tutorials/introductory/customizing.html#defining-your-own-style>`__ can be used to customise
43+
the plots generated by ``napari-matplotlib``.
44+
To use a custom style sheet:
45+
46+
1. Save it as ``napari-matplotlib.mplstyle``
47+
2. Put it in the Matplotlib configuration directory.
48+
The location of this directory varies on different computers,
49+
and can be found by calling :func:`matplotlib.get_configdir()`.

‎src/napari_matplotlib/base.py

Copy file name to clipboardExpand all lines: src/napari_matplotlib/base.py
+7-1Lines changed: 7 additions & 1 deletion
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
56
import matplotlib.style as mplstyle
67
import napari
78
from matplotlib.backends.backend_qtagg import (
@@ -16,6 +17,10 @@
1617

1718
__all__ = ["BaseNapariMPLWidget", "NapariMPLWidget", "SingleAxesWidget"]
1819

20+
_CUSTOM_STYLE_PATH = (
21+
Path(matplotlib.get_configdir()) / "napari-matplotlib.mplstyle"
22+
)
23+
1924

2025
class BaseNapariMPLWidget(QWidget):
2126
"""
@@ -46,7 +51,6 @@ def __init__(
4651
with mplstyle.context(self.mpl_style_sheet_path):
4752
self.canvas = FigureCanvas()
4853

49-
self.canvas.figure.patch.set_facecolor("none")
5054
self.canvas.figure.set_layout_engine("constrained")
5155
self.toolbar = NapariNavigationToolbar(
5256
self.canvas, parent=self
@@ -73,6 +77,8 @@ def mpl_style_sheet_path(self) -> Path:
7377
"""
7478
if self._mpl_style_sheet_path is not None:
7579
return self._mpl_style_sheet_path
80+
elif (_CUSTOM_STYLE_PATH).exists():
81+
return _CUSTOM_STYLE_PATH
7682
elif self._napari_theme_has_light_bg():
7783
return Path(__file__).parent / "styles" / "light.mplstyle"
7884
else:

‎src/napari_matplotlib/tests/test_theme.py

Copy file name to clipboardExpand all lines: src/napari_matplotlib/tests/test_theme.py
+28-20Lines changed: 28 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
from copy import deepcopy
2-
31
import shutil
2+
from copy import deepcopy
43
from pathlib import Path
54

65
import matplotlib
@@ -152,27 +151,36 @@ def find_mpl_stylesheet(name: str) -> Path:
152151
return Path(matplotlib.__path__[0]) / f"mpl-data/stylelib/{name}.mplstyle"
153152

154153

155-
def test_stylesheet_in_cwd(tmpdir, make_napari_viewer, image_data):
154+
def test_custom_stylesheet(make_napari_viewer, image_data):
156155
"""
157156
Test that a stylesheet in the current directory is given precidence.
158157
159158
Do this by copying over a stylesheet from matplotlib's built in styles,
160159
naming it correctly, and checking the colours are as expected.
161160
"""
162-
with tmpdir.as_cwd():
163-
# Copy Solarize_Light2 to current dir as if it was a user-overriden stylesheet.
164-
shutil.copy(find_mpl_stylesheet("Solarize_Light2"), "./user.mplstyle")
165-
viewer = make_napari_viewer()
166-
viewer.add_image(image_data[0], **image_data[1])
167-
widget = HistogramWidget(viewer)
168-
ax = widget.figure.gca()
169-
170-
# The axes should have a light brownish grey background:
171-
assert ax.get_facecolor() == to_rgba("#eee8d5")
172-
assert ax.patch.get_facecolor() == to_rgba("#eee8d5")
173-
174-
# The figure background and axis gridlines are light yellow:
175-
assert widget.figure.patch.get_facecolor() == to_rgba("#fdf6e3")
176-
for gridline in ax.get_xgridlines() + ax.get_ygridlines():
177-
assert gridline.get_visible() is True
178-
assert gridline.get_color() == "#fdf6e3"
161+
# Copy Solarize_Light2 as if it was a user-overriden stylesheet.
162+
style_sheet_path = (
163+
Path(matplotlib.get_configdir()) / "napari-matplotlib.mplstyle"
164+
)
165+
if style_sheet_path.exists():
166+
pytest.skip("Won't ovewrite existing custom style sheet.")
167+
shutil.copy(
168+
find_mpl_stylesheet("Solarize_Light2"),
169+
style_sheet_path,
170+
)
171+
172+
viewer = make_napari_viewer()
173+
viewer.add_image(image_data[0], **image_data[1])
174+
widget = HistogramWidget(viewer)
175+
assert widget.mpl_style_sheet_path == style_sheet_path
176+
ax = widget.figure.gca()
177+
178+
# The axes should have a light brownish grey background:
179+
assert ax.get_facecolor() == to_rgba("#eee8d5")
180+
assert ax.patch.get_facecolor() == to_rgba("#eee8d5")
181+
182+
# The figure background and axis gridlines are light yellow:
183+
assert widget.figure.patch.get_facecolor() == to_rgba("#fdf6e3")
184+
for gridline in ax.get_xgridlines() + ax.get_ygridlines():
185+
assert gridline.get_visible() is True
186+
assert gridline.get_color() == "#fdf6e3"

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.