I'm looking for a good circular/cyclic colormap to represent phase angle information (where the values are restricted to the range [0, 2π] and where 0 and 2π represent the same phase angle).
Background: I'd like to visualize normal modes by plotting both the power spectral density and the relative phase information of the oscillations across the system.
I'll admit that previously I used the 'rainbow' colormap for the power plot and the 'hsv' colormap for the phase plot (see [1]). However, the use of the rainbow colormap is extremely discouraged because of its lack of perceptual linearity and ordering [2][3]. So I switched to the 'coolwarm' colormap for the power plot which I quite like. Unfortunately, the 'hsv' colormap seems to introduce the same kind of visual distortions as the 'rainbow' map (and it also doesn't go along very well with the 'coolwarm' map since it looks kind of ugly and flashy in comparison).
Does anyone have a good recommendation for an alternative circular colormap which I could use for the phase plots?
Requirements:
It needs to be circular so that the values 0 and 2π are represented by the same color.
It should not introduce any visual distortions; in particular, it should be perceptually linear (which the 'hsv' colormap doesn't seem to be). I don't believe that perceptual ordering is such a big deal for phase information, but it would of course not do any harm.
It should be visually appealing when combined with the 'coolwarm' colormap. However, I'm not dead set on 'coolwarm' and am happy to consider other options if there is another nice pair of colormaps to visualize amplitude and phase information.
Bonus points if the colormap is available (or can be easily created) for use in matplotlib.
Many thanks for any suggestions!
[1] http://matplotlib.org/examples/color/colormaps_reference.html
[2] http://www.renci.org/~borland/pdfs/RainbowColorMap_VisViewpoints.pdf
[3] http://medvis.org/2012/08/21/rainbow-colormaps-what-are-they-good-for-absolutely-nothing/
It needs to be circular so that the values 0 and 2π are represented by the same color. It should not introduce any visual distortions; in particular, it should be perceptually linear (which the 'hsv' colormap doesn't seem to be).
Classes of colormaps ¶. 1 Sequential ¶. For the Sequential plots, the lightness value increases monotonically through the colormaps. This is good. Some of the L ∗ values in the ... 2 Sequential2 ¶. 3 Diverging ¶. 4 Cyclic ¶. 5 Qualitative ¶. More items
As of matplotlib version 3.0 there are built-in cyclic perceptually uniform colormaps. OK, just the one colormap for the time being, but with two choices of start and end along the cycle, namely twilight and twilight_shifted.
My CMasher package contains a large collection of scientific colormaps, including cyclic ones. Unlike twilight, which comes close to being perceptually uniform, all of CMasher's colormaps are perceptually uniform sequential. You can take a look at all of its colormaps in its online documentation.
As of matplotlib version 3.0 there are built-in cyclic perceptually uniform colormaps. OK, just the one colormap for the time being, but with two choices of start and end along the cycle, namely twilight
and twilight_shifted
.
A short example to demonstrate how they look:
import matplotlib.pyplot as plt import numpy as np # example data: argument of complex numbers around 0 N = 100 re, im = np.mgrid[-1:1:100j, -1:1:100j] angle = np.angle(re + 1j*im) cmaps = 'twilight', 'twilight_shifted' fig, axs = plt.subplots(ncols=len(cmaps), figsize=(9.5, 5.5)) for cmap, ax in zip(cmaps, axs): cf = ax.pcolormesh(re, im, angle, shading='gouraud', cmap=cmap) ax.set_title(cmap) ax.set_xlabel(r'$\operatorname{Re} z$') ax.set_ylabel(r'$\operatorname{Im} z$') ax.axis('scaled') cb = plt.colorbar(cf, ax=ax, orientation='horizontal') cb.set_label(r'$\operatorname{Arg} z$') fig.tight_layout()
The above produces the following figure:
These brand new colormaps are an amazing addition to the existing collection of perceptually uniform (sequential) colormaps, namely viridis, plasma, inferno, magma and cividis (the last one was a new addition in 2.2 which is not only perceptually uniform and thus colorblind-friendly, but it should look as close as possible to colorblind and non-colorblind people).
You could try the "husl" system, which is similar to hls/hsv but with better visual properties. It is available in seaborn and as a standalone package.
Here's a simple example:
import numpy as np from numpy import sin, cos, pi import matplotlib.pyplot as plt import seaborn as sns n = 314 theta = np.linspace(0, 2 * pi, n) x = cos(theta) y = sin(theta) f = plt.figure(figsize=(10, 5)) with sns.color_palette("husl", n): ax = f.add_subplot(121) ax.plot([np.zeros_like(x), x], [np.zeros_like(y), y], lw=3) ax.set_axis_off() ax.set_title("HUSL space") with sns.color_palette("hls", n): ax = f.add_subplot(122) ax.plot([np.zeros_like(x), x], [np.zeros_like(y), y], lw=3) ax.set_axis_off() ax.set_title("HLS space") f.tight_layout()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With