complex_colormap
complex_colormap copied to clipboard
Customizable squashing function
Mapping [0, ∞) to [0, 1] can be done many different ways, and I found some worked better or worse for different functions.
I originally used mpmath.cplot for this, which combines squashing and colormapping into the same function default_color_function(), but maybe more logical to separate them? Like specify mapping and colormap as parameters to cplot, like matplotlib's norm parameter.
At first I thought: Why map the interval at all? Real-valued plots simply take the min and max values of the function on the plotted domain and identify those values with the lower and upper end of the color map. We could do the same for abs(z). Done.
Then I realized that that identifying 0 with black and infinity with white has one very nice propery: Complex angles don't have meaning for 0 and infinity just like hue doesn't have meaning for black and white. This is a correspondence we should not simply let go. So yeah, let's map. :)
I'm not sure if I agree to make the map configurable though. Introducing one fixed map will make all plots made with complex_colormap comparable. If the map is configurable, users may be tempted to "highlight" certain aspects of their data, effectively distorting it and making the plot misleading. One thing about a fixed map is one particular map presents itself naturally. In the current implementation,
J = (1.0 - (1 / (1.0 + np.abs(z)**0.3))) * 100
set 0.3 to 1 to get
x = abs(z)
J = x / (x + 1) * 100
Probably redundant, but I thought I'd mention this diagram which I often come back to for this sort of mapping (although most of the time I just end up using tanh):
(source)
The formula in @nschloe's comment above kind of matches the last one in the diagram,
with the difference that they do z / (abs(z) + 1), not abs(z) / (abs(z) + 1).
One nice property of
x***alpha / (x**alpha + 1)
is that
f(x) = 1 - f(1/x)
This makes sure that when comparing inverses, e.g., tan(z) and 1/tan(z), whites and blacks are exactly inverted as well. This is not true for any of the depicted functions except x / (1+x). (This can easily be spotted by the fact that the curves don't go through (1, 0.5).)
If the map is configurable, users may be tempted to "highlight" certain aspects of their data, effectively distorting it and making the plot misleading.
That's what I do, though. 😅