Skip to content
Snippets Groups Projects
Commit 825d30f8 authored by Jan Caron's avatar Jan Caron Committed by Jan Caron
Browse files

Fix for matplotlib installation.

Moved .mplstyle files inside vis.
setup.cfg: added options.packages.find
    removed 3Dplot requirements (for now).
setup.py: moved stylesheet installation to vis.tools, now optional.
vis.tools: also added a use_style contextmanager that dynamically uses
    local styles (in package) or styles installed in user config folder.
colors/decorators/plot2d: now use the new use_style contextmanager.
parent 6d0b215d
No related branches found
No related tags found
No related merge requests found
...@@ -50,6 +50,7 @@ test_docs: ...@@ -50,6 +50,7 @@ test_docs:
test_install: test_install:
stage: test stage: test
image: continuumio/miniconda3:latest image: continuumio/miniconda3:latest
before_script: [] # before_script not needed here!
script: script:
- pip install .[all] - pip install .[all]
...@@ -70,7 +71,7 @@ pages: ...@@ -70,7 +71,7 @@ pages:
pypi: pypi:
stage: deploy stage: deploy
image: continuumio/miniconda3:latest image: continuumio/miniconda3:latest
before_script: [] before_script: [] # before_script not needed here!
script: script:
- pip install twine - pip install twine
- python setup.py sdist bdist_wheel - python setup.py sdist bdist_wheel
......
...@@ -36,7 +36,6 @@ packages = find: ...@@ -36,7 +36,6 @@ packages = find:
python_requires = >=3.7 python_requires = >=3.7
setup_requires = setup_requires =
setuptools setuptools
matplotlib>=3
tests_require = tests_require =
coverage coverage
pytest pytest
...@@ -51,10 +50,10 @@ install_requires = ...@@ -51,10 +50,10 @@ install_requires =
scipy scipy
Pillow Pillow
[options.packages.find]
where = src
[options.extras_require] [options.extras_require]
3Dplot =
qt==4.8
mayavi==4.5
io = io =
hyperspy hyperspy
fftw = fftw =
...@@ -62,8 +61,6 @@ fftw = ...@@ -62,8 +61,6 @@ fftw =
colors = colors =
cmocean cmocean
all = all =
qt==4.8
mayavi==4.5
hyperspy hyperspy
pyfftw pyfftw
cmocean cmocean
......
...@@ -2,9 +2,8 @@ ...@@ -2,9 +2,8 @@
# coding=utf-8 # coding=utf-8
"""Setup for testing, building, distributing and installing the 'EMPyRe'-package""" """Setup for testing, building, distributing and installing the 'EMPyRe'-package"""
import os import os
import glob
import shutil
import subprocess import subprocess
from setuptools import setup, config from setuptools import setup, config
...@@ -27,16 +26,3 @@ with open(os.path.join(os.path.dirname(__file__), 'src', 'empyre', 'version.py') ...@@ -27,16 +26,3 @@ with open(os.path.join(os.path.dirname(__file__), 'src', 'empyre', 'version.py')
# Run setup (reads metadata & options from setup.cfg): # Run setup (reads metadata & options from setup.cfg):
print(R'running setup.py') print(R'running setup.py')
setup() setup()
import matplotlib as mpl
# Find matplotlib styles:
BASE_LIBRARY_PATH = os.path.join(mpl.get_data_path(), 'stylelib')
STYLE_PATH = os.path.join(os.getcwd(), 'mplstyles')
style_files = glob.glob(os.path.join(STYLE_PATH, '*.mplstyle'))
# Copy them to the local matplotlib styles folder:
print(f'copying matplotlib stylesheets to {BASE_LIBRARY_PATH}')
for style_path in style_files:
_, fname = os.path.split(style_path)
dest = os.path.join(BASE_LIBRARY_PATH, fname)
shutil.copy(style_path, dest)
...@@ -24,6 +24,8 @@ from matplotlib.ticker import FixedLocator ...@@ -24,6 +24,8 @@ from matplotlib.ticker import FixedLocator
from mpl_toolkits.mplot3d import Axes3D # noqa: F401 from mpl_toolkits.mplot3d import Axes3D # noqa: F401
from matplotlib.patches import Circle from matplotlib.patches import Circle
from .tools import use_style
__all__ = ['Colormap3D', 'ColormapCubehelix', 'ColormapPerception', 'ColormapHLS', 'ColormapClassic', __all__ = ['Colormap3D', 'ColormapCubehelix', 'ColormapPerception', 'ColormapHLS', 'ColormapClassic',
'ColormapTransparent', 'cmaps', 'CMAP_CIRCULAR_DEFAULT', 'interpolate_color'] 'ColormapTransparent', 'cmaps', 'CMAP_CIRCULAR_DEFAULT', 'interpolate_color']
...@@ -132,7 +134,7 @@ class Colormap3D(colors.Colormap, metaclass=abc.ABCMeta): ...@@ -132,7 +134,7 @@ class Colormap3D(colors.Colormap, metaclass=abc.ABCMeta):
if grayscale: if grayscale:
color_wheel = color_wheel.convert('LA') color_wheel = color_wheel.convert('LA')
# Plot the color wheel: # Plot the color wheel:
with plt.style.context('empyre-image'): # Only works on axes created WITHIN context! with use_style('empyre-image'): # Only works on axes created WITHIN context!
if axis is None: # If no axis is set, find the current or create a new one: if axis is None: # If no axis is set, find the current or create a new one:
fig = plt.figure() fig = plt.figure()
axis = fig.add_subplot(1, 1, 1, aspect='equal') axis = fig.add_subplot(1, 1, 1, aspect='equal')
...@@ -293,7 +295,7 @@ class ColormapCubehelix(colors.LinearSegmentedColormap, Colormap3D): ...@@ -293,7 +295,7 @@ class ColormapCubehelix(colors.LinearSegmentedColormap, Colormap3D):
""" """
self._log.debug('Calling plot_helix') self._log.debug('Calling plot_helix')
with plt.style.context('empyre-plot'): with use_style('empyre-plot'):
fig = plt.figure(figsize=figsize, constrained_layout=True) fig = plt.figure(figsize=figsize, constrained_layout=True)
gs = fig.add_gridspec(2, 1, height_ratios=[8, 1]) gs = fig.add_gridspec(2, 1, height_ratios=[8, 1])
# Main plot: # Main plot:
......
...@@ -17,6 +17,7 @@ from mpl_toolkits.axes_grid1.anchored_artists import AnchoredSizeBar ...@@ -17,6 +17,7 @@ from mpl_toolkits.axes_grid1.anchored_artists import AnchoredSizeBar
from mpl_toolkits.axes_grid1.inset_locator import inset_axes from mpl_toolkits.axes_grid1.inset_locator import inset_axes
from . import colors from . import colors
from .tools import use_style
from ..fields.field import Field from ..fields.field import Field
...@@ -338,7 +339,7 @@ def colorbar(im, fig=None, cbar_axis=None, axes=None, position='right', pad=0.02 ...@@ -338,7 +339,7 @@ def colorbar(im, fig=None, cbar_axis=None, axes=None, position='right', pad=0.02
bounds = [left, bottom-pad-thickness, right-left, thickness] bounds = [left, bottom-pad-thickness, right-left, thickness]
cbar_axis = fig.add_axes(bounds) cbar_axis = fig.add_axes(bounds)
# Create the colorbar: # Create the colorbar:
with plt.style.context('empyre-image'): with use_style('empyre-image'):
if position in ('left', 'right'): if position in ('left', 'right'):
cb = plt.colorbar(im, cax=cbar_axis, orientation='vertical') cb = plt.colorbar(im, cax=cbar_axis, orientation='vertical')
cb.ax.yaxis.set_ticks_position(position) cb.ax.yaxis.set_ticks_position(position)
......
...@@ -13,6 +13,7 @@ from matplotlib.colors import LinearSegmentedColormap ...@@ -13,6 +13,7 @@ from matplotlib.colors import LinearSegmentedColormap
from PIL import Image from PIL import Image
from . import colors from . import colors
from .tools import use_style
from ..fields.field import Field from ..fields.field import Field
...@@ -68,7 +69,7 @@ def imshow(field, axis=None, cmap=None, **kwargs): ...@@ -68,7 +69,7 @@ def imshow(field, axis=None, cmap=None, **kwargs):
cmap = cmocean.cm.balance cmap = cmocean.cm.balance
except ImportError: except ImportError:
_log.info('cmocean.balance not found, fallback to rRdBu!') _log.info('cmocean.balance not found, fallback to rRdBu!')
cmap = 'RdBu_r' # '_r' for reverse! cmap = plt.get_cmap('RdBu_r') # '_r' for reverse!
elif isinstance(cmap, str): # make sure we have a Colormap object (and not a string): elif isinstance(cmap, str): # make sure we have a Colormap object (and not a string):
cmap = plt.get_cmap(cmap) cmap = plt.get_cmap(cmap)
if cmap.name.replace('_r', '') in DIVERGING_CMAPS: # 'replace' also matches reverted cmaps! if cmap.name.replace('_r', '') in DIVERGING_CMAPS: # 'replace' also matches reverted cmaps!
...@@ -89,7 +90,7 @@ def imshow(field, axis=None, cmap=None, **kwargs): ...@@ -89,7 +90,7 @@ def imshow(field, axis=None, cmap=None, **kwargs):
dim_v, dim_u, s_v, s_u = *squeezed_field.dim, *squeezed_field.scale dim_v, dim_u, s_v, s_u = *squeezed_field.dim, *squeezed_field.scale
kwargs.setdefault('extent', (0, dim_u * s_u, 0, dim_v * s_v)) kwargs.setdefault('extent', (0, dim_u * s_u, 0, dim_v * s_v))
# Plot with the empyre style context: # Plot with the empyre style context:
with plt.style.context('empyre-image'): # Only works on axes created WITHIN context! with use_style('empyre-image'): # Only works on axes created WITHIN context!
if axis is None: # If no axis is set, find the current or create a new one: if axis is None: # If no axis is set, find the current or create a new one:
axis = plt.gca() axis = plt.gca()
return axis.imshow(squeezed_field, cmap=cmap, **kwargs) return axis.imshow(squeezed_field, cmap=cmap, **kwargs)
...@@ -132,7 +133,7 @@ def contour(field, axis=None, **kwargs): ...@@ -132,7 +133,7 @@ def contour(field, axis=None, **kwargs):
kwargs.setdefault('linestyles', 'dotted') kwargs.setdefault('linestyles', 'dotted')
kwargs.setdefault('linewidths', 2) kwargs.setdefault('linewidths', 2)
# Plot with the empyre style context: # Plot with the empyre style context:
with plt.style.context('empyre-image'): # Only works on axes created WITHIN context! with use_style('empyre-image'): # Only works on axes created WITHIN context!
if axis is None: # If no axis is set, find the current or create a new one: if axis is None: # If no axis is set, find the current or create a new one:
axis = plt.gca() axis = plt.gca()
axis.set_aspect('equal') axis.set_aspect('equal')
...@@ -197,7 +198,7 @@ def colorvec(field, axis=None, **kwargs): ...@@ -197,7 +198,7 @@ def colorvec(field, axis=None, **kwargs):
dim_v, dim_u, s_v, s_u = *squeezed_field.dim, *squeezed_field.scale dim_v, dim_u, s_v, s_u = *squeezed_field.dim, *squeezed_field.scale
kwargs.setdefault('extent', (0, dim_u * s_u, 0, dim_v * s_v)) kwargs.setdefault('extent', (0, dim_u * s_u, 0, dim_v * s_v))
# Plot with the empyre style context: # Plot with the empyre style context:
with plt.style.context('empyre-image'): # Only works on axes created WITHIN context! with use_style('empyre-image'): # Only works on axes created WITHIN context!
if axis is None: # If no axis is set, find the current or create a new one: if axis is None: # If no axis is set, find the current or create a new one:
axis = plt.gca() axis = plt.gca()
return axis.imshow(Image.fromarray(rgb), **kwargs) return axis.imshow(Image.fromarray(rgb), **kwargs)
...@@ -255,7 +256,7 @@ def cosine_contours(field, axis=None, gain='auto', cmap=None, **kwargs): ...@@ -255,7 +256,7 @@ def cosine_contours(field, axis=None, gain='auto', cmap=None, **kwargs):
dim_v, dim_u, s_v, s_u = *squeezed_field.dim, *squeezed_field.scale dim_v, dim_u, s_v, s_u = *squeezed_field.dim, *squeezed_field.scale
kwargs.setdefault('extent', (0, dim_u * s_u, 0, dim_v * s_v)) kwargs.setdefault('extent', (0, dim_u * s_u, 0, dim_v * s_v))
# Plot with the empyre style context: # Plot with the empyre style context:
with plt.style.context('empyre-image'): # Only works on axes created WITHIN context! with use_style('empyre-image'): # Only works on axes created WITHIN context!
if axis is None: # If no axis is set, find the current or create a new one: if axis is None: # If no axis is set, find the current or create a new one:
axis = plt.gca() axis = plt.gca()
return axis.imshow(contours, cmap=cmap, **kwargs) return axis.imshow(contours, cmap=cmap, **kwargs)
...@@ -376,7 +377,7 @@ def quiver(field, axis=None, color_angles=False, cmap=None, n_bin='auto', bin_wi ...@@ -376,7 +377,7 @@ def quiver(field, axis=None, color_angles=False, cmap=None, n_bin='auto', bin_wi
kwargs.setdefault('minshaft', 2) kwargs.setdefault('minshaft', 2)
kwargs.setdefault('linewidths', 1) kwargs.setdefault('linewidths', 1)
# Plot with the empyre style context: # Plot with the empyre style context:
with plt.style.context('empyre-image'): # Only works on axes created WITHIN context! with use_style('empyre-image'): # Only works on axes created WITHIN context!
if axis is None: # If no axis is set, find the current or create a new one: if axis is None: # If no axis is set, find the current or create a new one:
axis = plt.gca() axis = plt.gca()
axis.set_xlim(0, u_lim) axis.set_xlim(0, u_lim)
......
...@@ -5,16 +5,21 @@ ...@@ -5,16 +5,21 @@
"""This module provides helper functions to the vis module.""" """This module provides helper functions to the vis module."""
import os
import glob
import shutil
import logging import logging
from numbers import Number from numbers import Number
from contextlib import contextmanager
import numpy as np import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
from ..fields.field import Field from ..fields.field import Field
__all__ = ['new', 'savefig', 'calc_figsize'] __all__ = ['new', 'savefig', 'calc_figsize', 'use_style', 'copy_mpl_stylesheets']
_log = logging.getLogger(__name__) _log = logging.getLogger(__name__)
...@@ -79,10 +84,10 @@ def new(nrows=1, ncols=1, mode='image', figsize=None, textwidth=None, width_scal ...@@ -79,10 +84,10 @@ def new(nrows=1, ncols=1, mode='image', figsize=None, textwidth=None, width_scal
assert isinstance(aspect, Number), 'aspect has to be None, a number or a field instance squeezable to 2D!' assert isinstance(aspect, Number), 'aspect has to be None, a number or a field instance squeezable to 2D!'
figsize = calc_figsize(width_scale=width_scale, aspect=aspect, textwidth=textwidth) figsize = calc_figsize(width_scale=width_scale, aspect=aspect, textwidth=textwidth)
if mode == 'image': if mode == 'image':
with plt.style.context('empyre-image'): with use_style('empyre-image'):
return plt.subplots(nrows=nrows, ncols=ncols, figsize=figsize, **kwargs) return plt.subplots(nrows=nrows, ncols=ncols, figsize=figsize, **kwargs)
else: # mode == 'plot': else: # mode == 'plot':
with plt.style.context('empyre-plot'): with use_style('empyre-plot'):
return plt.subplots(nrows=nrows, ncols=ncols, figsize=figsize, **kwargs) return plt.subplots(nrows=nrows, ncols=ncols, figsize=figsize, **kwargs)
...@@ -101,7 +106,7 @@ def savefig(fname, **kwargs): ...@@ -101,7 +106,7 @@ def savefig(fname, **kwargs):
""" """
_log.debug('Calling savefig') _log.debug('Calling savefig')
with plt.style.context('empyre-save'): with use_style('empyre-save'):
plt.savefig(fname, **kwargs) plt.savefig(fname, **kwargs)
...@@ -143,3 +148,48 @@ def calc_figsize(textwidth, width_scale=1, aspect=1): ...@@ -143,3 +148,48 @@ def calc_figsize(textwidth, width_scale=1, aspect=1):
raise ValueError(f"aspect has to be either a number, 'same' or 'golden'! Was {aspect}!") raise ValueError(f"aspect has to be either a number, 'same' or 'golden'! Was {aspect}!")
fig_size = [fig_width, fig_height] # Both in inches fig_size = [fig_width, fig_height] # Both in inches
return fig_size return fig_size
@contextmanager
def use_style(stylename):
"""Context that uses a matplotlib stylesheet. Can fall back to local mpl stylesheets if necessary!
Parameters
----------
stylename : str
A style specification.
Yields
-------
context
Context manager for using style settings temporarily.
"""
try: # Try to load the style directly (works if it is installed somewhere mpl looks for it):
with plt.style.context(stylename) as context:
yield context
except OSError: # Stylesheet not found, use local ones:
mplstyle_path = os.path.join(os.path.dirname(__file__), 'mplstyles', f'{stylename}.mplstyle')
with plt.style.context(mplstyle_path) as context:
yield context
def copy_mpl_stylesheets():
"""Copy matplotlib styles to the users matplotlib config directory. Useful if you want to utilize them elsewhere.
Notes
-----
You might need to restart your Python session for the stylesheets to be recognized/found!
"""
# Find matplotlib styles:
user_stylelib_path = os.path.join(mpl.get_configdir(), 'stylelib')
vis_dir = os.path.dirname(__file__)
style_files = glob.glob(os.path.join(vis_dir, 'mplstyles', '*.mplstyle'))
# Copy them to the local matplotlib styles folder:
if not os.path.exists(user_stylelib_path):
os.makedirs(user_stylelib_path)
for style_path in style_files:
_, fname = os.path.split(style_path)
dest = os.path.join(user_stylelib_path, fname)
shutil.copy(style_path, dest)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment