|
8 | 8 | from . import util as _util
|
9 | 9 |
|
10 | 10 |
|
11 |
| -def _register_cmap_clip(name, original_cmap, alpha): |
12 |
| - """Create a color map with "over" and "under" values.""" |
13 |
| - from matplotlib.colors import LinearSegmentedColormap |
14 |
| - cdata = _plt.cm.datad[original_cmap] |
15 |
| - if isinstance(cdata, dict): |
16 |
| - cmap = LinearSegmentedColormap(name, cdata) |
| 11 | +def _make_extreme(rgba): |
| 12 | + """Make bright colors darker, dark colors brighter, both less saturated.""" |
| 13 | + # The package `colorspacious` must be installed for this to work: |
| 14 | + from colorspacious import cspace_convert |
| 15 | + lightness_step = 25 |
| 16 | + chroma_factor = 0.7 |
| 17 | + j, c, h = cspace_convert(rgba[:3], 'sRGB1', 'JCh') |
| 18 | + if j > 50: |
| 19 | + j -= lightness_step |
17 | 20 | else:
|
18 |
| - cmap = LinearSegmentedColormap.from_list(name, cdata) |
19 |
| - cmap.set_over([alpha * c + 1 - alpha for c in cmap(1.0)[:3]]) |
20 |
| - cmap.set_under([alpha * c + 1 - alpha for c in cmap(0.0)[:3]]) |
| 21 | + j += lightness_step |
| 22 | + c *= chroma_factor |
| 23 | + rgba[:3] = _np.clip(cspace_convert([j, c, h], 'JCh', 'sRGB1'), 0, 1) |
| 24 | + return rgba |
| 25 | + |
| 26 | + |
| 27 | +def _register_cmap_with_extremes(name, original_name, **kwargs): |
| 28 | + """Create a color map with "under" and "over" values.""" |
| 29 | + cmap = _plt.get_cmap(original_name) |
| 30 | + cmap = cmap.with_extremes(**kwargs) |
| 31 | + cmap.name = name |
21 | 32 | _plt.colormaps.register(cmap=cmap)
|
22 | 33 |
|
23 | 34 |
|
| 35 | +# The following under/over values have been calculated with _make_extreme(). |
| 36 | +# They are hard-coded to avoid a dependency on the library "colorspacious". |
| 37 | +_register_cmap_with_extremes('cividis_clip', 'cividis', |
| 38 | + under=[0.3581123750444155, 0.4308239004832521, 0.5431626919728758, 1.0], |
| 39 | + over=[0.748794386079359, 0.6952014568472878, 0.27380570592765713, 1.0]) |
| 40 | +_register_cmap_with_extremes('cividis_r_clip', 'cividis_r', |
| 41 | + under=[0.748794386079359, 0.6952014568472878, 0.27380570592765713, 1.0], |
| 42 | + over=[0.3581123750444155, 0.4308239004832521, 0.5431626919728758, 1.0]) |
| 43 | +_register_cmap_with_extremes('inferno_clip', 'inferno', |
| 44 | + under=[0.3223737972210511, 0.3196564508033573, 0.3474201893768059, 1.0], |
| 45 | + over=[0.7759331577663429, 0.7815136432099379, 0.5546145677840046, 1.0]) |
| 46 | +_register_cmap_with_extremes('inferno_r_clip', 'inferno_r', |
| 47 | + under=[0.7759331577663429, 0.7815136432099379, 0.5546145677840046, 1.0], |
| 48 | + over=[0.3223737972210511, 0.3196564508033573, 0.3474201893768059, 1.0]) |
| 49 | +_register_cmap_with_extremes('magma_clip', 'magma', |
| 50 | + under=[0.3223737972210511, 0.3196564508033573, 0.3474201893768059, 1.0], |
| 51 | + over=[0.7755917106347097, 0.7765145738617047, 0.621366899182334, 1.0]) |
| 52 | +_register_cmap_with_extremes('magma_r_clip', 'magma_r', |
| 53 | + under=[0.7755917106347097, 0.7765145738617047, 0.621366899182334, 1.0], |
| 54 | + over=[0.3223737972210511, 0.3196564508033573, 0.3474201893768059, 1.0]) |
| 55 | +_register_cmap_with_extremes('plasma_clip', 'plasma', |
| 56 | + under=[0.3425913695445096, 0.42529714344969144, 0.66039452922638, 1.0], |
| 57 | + over=[0.723897190872765, 0.7507494961114689, 0.2574503078804632, 1.0]) |
| 58 | +_register_cmap_with_extremes('plasma_r_clip', 'plasma_r', |
| 59 | + under=[0.723897190872765, 0.7507494961114689, 0.2574503078804632, 1.0], |
| 60 | + over=[0.3425913695445096, 0.42529714344969144, 0.66039452922638, 1.0]) |
| 61 | +_register_cmap_with_extremes('viridis_clip', 'viridis', |
| 62 | + under=[0.536623905475994, 0.3775029064902613, 0.5655492658877974, 1.0], |
| 63 | + over=[0.7453792828268919, 0.6916769483054797, 0.24219807423955453, 1.0]) |
| 64 | +_register_cmap_with_extremes('viridis_r_clip', 'viridis_r', |
| 65 | + under=[0.7453792828268919, 0.6916769483054797, 0.24219807423955453, 1.0], |
| 66 | + over=[0.536623905475994, 0.3775029064902613, 0.5655492658877974, 1.0]) |
| 67 | + |
| 68 | +_register_cmap_with_extremes('RdBu_clip', 'RdBu', |
| 69 | + under=[0.6931181505544421, 0.3643024937396605, 0.40355267940576434, 1.0], |
| 70 | + over=[0.3844199587527661, 0.4705632423745359, 0.597949800233206, 1.0]) |
| 71 | +_register_cmap_with_extremes('RdBu_r_clip', 'RdBu_r', |
| 72 | + under=[0.3844199587527661, 0.4705632423745359, 0.597949800233206, 1.0], |
| 73 | + over=[0.6931181505544421, 0.3643024937396605, 0.40355267940576434, 1.0]) |
| 74 | + |
24 | 75 | # The 'coolwarm' colormap is based on the paper
|
25 | 76 | # "Diverging Color Maps for Scientific Visualization" by Kenneth Moreland
|
26 |
| -# http://www.sandia.gov/~kmorel/documents/ColorMaps/ |
27 |
| -# already registered in MPL 3.9.0 |
28 |
| -try: |
29 |
| - _register_cmap_clip('coolwarm_clip', 'coolwarm', 0.7) |
30 |
| -except ImportError: |
31 |
| - pass |
| 77 | +# https://www.kennethmoreland.com/color-maps/ColorMapsExpanded.pdf |
| 78 | +_register_cmap_with_extremes('coolwarm_clip', 'coolwarm', |
| 79 | + under=[0.510515040101537, 0.5812838578665308, 0.8594377816482693, 1.0], |
| 80 | + over=[0.9464304571740522, 0.43619922642510556, 0.4340300540797168, 1.0]) |
| 81 | +_register_cmap_with_extremes('coolwarm_r_clip', 'coolwarm_r', |
| 82 | + under=[0.9464304571740522, 0.43619922642510556, 0.4340300540797168, 1.0], |
| 83 | + over=[0.510515040101537, 0.5812838578665308, 0.8594377816482693, 1.0]) |
32 | 84 |
|
33 | 85 |
|
34 | 86 | def _register_cmap_transparent(name, color):
|
@@ -180,7 +232,7 @@ def _visible_secondarysources(x0, n0, grid):
|
180 | 232 | """Determine secondary sources which lie within *grid*."""
|
181 | 233 | x, y = _util.as_xyz_components(grid[:2])
|
182 | 234 | idx = _np.where((x0[:, 0] > x.min()) & (x0[:, 0] < x.max()) &
|
183 |
| - (x0[:, 1] > y.min()) & (x0[:, 1] < x.max())) |
| 235 | + (x0[:, 1] > y.min()) & (x0[:, 1] < x.max())) |
184 | 236 | idx = _np.squeeze(idx)
|
185 | 237 |
|
186 | 238 | return x0[idx, :], n0[idx, :]
|
@@ -325,8 +377,8 @@ def amplitude(p, grid, *, xnorm=None, cmap='coolwarm_clip',
|
325 | 377 | return im
|
326 | 378 |
|
327 | 379 |
|
328 |
| -def level(p, grid, *, xnorm=None, power=False, cmap=None, vmax=3, vmin=-50, |
329 |
| - colorbar_kwargs=None, **kwargs): |
| 380 | +def level(p, grid, *, xnorm=None, power=False, cmap='viridis_clip', |
| 381 | + vmax=3, vmin=-50, colorbar_kwargs=None, **kwargs): |
330 | 382 | """Two-dimensional plot of level (dB) of sound field.
|
331 | 383 |
|
332 | 384 | Takes the same parameters as `sfs.plot2d.amplitude()`.
|
@@ -383,7 +435,7 @@ def level_contour(p, grid, *, xnorm=None, power=False,
|
383 | 435 | def particles(x, *, trim=None, ax=None, xlabel='x (m)', ylabel='y (m)',
|
384 | 436 | edgecolors=None, marker='.', s=15, **kwargs):
|
385 | 437 | """Plot particle positions as scatter plot.
|
386 |
| - |
| 438 | +
|
387 | 439 | Parameters
|
388 | 440 | ----------
|
389 | 441 | x : triple or pair of array_like
|
|
0 commit comments