Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork7.9k
Add asinh axis scaling (*smooth* symmetric logscale)#21178
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
Uh oh!
There was an error while loading.Please reload this page.
Changes fromall commits
7ec127a
15ff4ec
9680432
3f69788
dd4f4d8
1ec0b22
2b0d588
2002cb3
070d984
8495f7b
279c38b
76d9b42
8143153
800ef38
0ad43a5
ba597de
80f2600
65eff09
8168e56
0249861
9fd8b0c
8d7c2ad
ae57d8d
b01d03c
e0dcff7
3d92406
7bec3f4
97693e8
a1af12c
4b23326
555bac1
545faf2
a2b210d
8a258cf
5a03297
de30538
3e487a6
c64d0c4
e43cbfd
File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading.Please reload this page.
Jump to
Uh oh!
There was an error while loading.Please reload this page.
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -21,6 +21,7 @@ Classes | ||
:toctree: _as_gen/ | ||
:template: autosummary.rst | ||
AsinhNorm | ||
BoundaryNorm | ||
Colormap | ||
CenteredNorm | ||
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
New axis scale ``asinh`` (experimental) | ||
--------------------------------------- | ||
The new ``asinh`` axis scale offers an alternative to ``symlog`` that | ||
rwpenney marked this conversation as resolved. Show resolvedHide resolvedUh oh!There was an error while loading.Please reload this page. | ||
smoothly transitions between the quasi-linear and asymptotically logarithmic | ||
regions of the scale. This is based on an arcsinh transformation that | ||
allows plotting both positive and negative values that span many orders | ||
of magnitude. | ||
QuLogic marked this conversation as resolved. Show resolvedHide resolvedUh oh!There was an error while loading.Please reload this page. | ||
.. plot:: | ||
import matplotlib.pyplot as plt | ||
import numpy as np | ||
fig, (ax0, ax1) = plt.subplots(1, 2, sharex=True) | ||
x = np.linspace(-3, 6, 100) | ||
ax0.plot(x, x) | ||
ax0.set_yscale('symlog') | ||
ax0.grid() | ||
ax0.set_title('symlog') | ||
ax1.plot(x, x) | ||
ax1.set_yscale('asinh') | ||
ax1.grid() | ||
ax1.set_title(r'$sinh^{-1}$') | ||
for p in (-2, 2): | ||
for ax in (ax0, ax1): | ||
c = plt.Circle((p, p), radius=0.5, fill=False, | ||
color='red', alpha=0.8, lw=3) | ||
ax.add_patch(c) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,42 +1,84 @@ | ||
""" | ||
================================== | ||
Colormap NormalizationsSymLogNorm | ||
================================== | ||
Demonstration of using norm to map colormaps onto data in non-linear ways. | ||
.. redirect-from:: /gallery/userdemo/colormap_normalization_symlognorm | ||
""" | ||
############################################################################### | ||
# Synthetic dataset consisting of two humps, one negative and one positive, | ||
# the positive with 8-times the amplitude. | ||
# Linearly, the negative hump is almost invisible, | ||
# and it is very difficult to see any detail of its profile. | ||
# With the logarithmic scaling applied to both positive and negative values, | ||
# it is much easier to see the shape of each hump. | ||
# | ||
# See `~.colors.SymLogNorm`. | ||
import numpy as np | ||
import matplotlib.pyplot as plt | ||
import matplotlib.colors as colors | ||
def rbf(x, y): | ||
return 1.0 / (1 + 5 * ((x ** 2) + (y ** 2))) | ||
N = 200 | ||
gain = 8 | ||
X, Y = np.mgrid[-3:3:complex(0, N), -2:2:complex(0, N)] | ||
Z1 = rbf(X + 0.5, Y + 0.5) | ||
Z2 = rbf(X - 0.5, Y - 0.5) | ||
Z = gain * Z1 - Z2 | ||
shadeopts = {'cmap': 'PRGn', 'shading': 'gouraud'} | ||
colormap = 'PRGn' | ||
lnrwidth = 0.5 | ||
fig, ax = plt.subplots(2, 1, sharex=True, sharey=True) | ||
pcm = ax[0].pcolormesh(X, Y, Z, | ||
norm=colors.SymLogNorm(linthresh=lnrwidth, linscale=1, | ||
vmin=-gain, vmax=gain, base=10), | ||
**shadeopts) | ||
fig.colorbar(pcm, ax=ax[0], extend='both') | ||
ax[0].text(-2.5, 1.5, 'symlog') | ||
pcm = ax[1].pcolormesh(X, Y, Z,vmin=-gain, vmax=gain, | ||
**shadeopts) | ||
fig.colorbar(pcm, ax=ax[1], extend='both') | ||
ax[1].text(-2.5, 1.5, 'linear') | ||
############################################################################### | ||
# In order to find the best visualization for any particular dataset, | ||
# it may be necessary to experiment with multiple different color scales. | ||
# As well as the `~.colors.SymLogNorm` scaling, there is also | ||
# the option of using `~.colors.AsinhNorm` (experimental), which has a smoother | ||
# transition between the linear and logarithmic regions of the transformation | ||
# applied to the data values, "Z". | ||
# In the plots below, it may be possible to see contour-like artifacts | ||
# around each hump despite there being no sharp features | ||
# in the dataset itself. The ``asinh`` scaling shows a smoother shading | ||
# of each hump. | ||
fig, ax = plt.subplots(2, 1, sharex=True, sharey=True) | ||
pcm = ax[0].pcolormesh(X, Y, Z, | ||
norm=colors.SymLogNorm(linthresh=lnrwidth, linscale=1, | ||
vmin=-gain, vmax=gain, base=10), | ||
**shadeopts) | ||
fig.colorbar(pcm, ax=ax[0], extend='both') | ||
ax[0].text(-2.5, 1.5, 'symlog') | ||
pcm = ax[1].pcolormesh(X, Y, Z, | ||
norm=colors.AsinhNorm(linear_width=lnrwidth, | ||
vmin=-gain, vmax=gain), | ||
**shadeopts) | ||
fig.colorbar(pcm, ax=ax[1], extend='both') | ||
ax[1].text(-2.5, 1.5, 'asinh') | ||
plt.show() |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
""" | ||
============ | ||
Asinh Demo | ||
============ | ||
rwpenney marked this conversation as resolved. Show resolvedHide resolvedUh oh!There was an error while loading.Please reload this page. | ||
Illustration of the `asinh <.scale.AsinhScale>` axis scaling, | ||
which uses the transformation | ||
.. math:: | ||
a \\rightarrow a_0 \\sinh^{-1} (a / a_0) | ||
For coordinate values close to zero (i.e. much smaller than | ||
the "linear width" :math:`a_0`), this leaves values essentially unchanged: | ||
.. math:: | ||
a \\rightarrow a + {\\cal O}(a^3) | ||
but for larger values (i.e. :math:`|a| \\gg a_0`, this is asymptotically | ||
.. math:: | ||
a \\rightarrow a_0 \\, {\\rm sgn}(a) \\ln |a| + {\\cal O}(1) | ||
As with the `symlog <.scale.SymmetricalLogScale>` scaling, | ||
this allows one to plot quantities | ||
that cover a very wide dynamic range that includes both positive | ||
and negative values. However, ``symlog`` involves a transformation | ||
that has discontinuities in its gradient because it is built | ||
from *separate* linear and logarithmic transformations. | ||
The ``asinh`` scaling uses a transformation that is smooth | ||
for all (finite) values, which is both mathematically cleaner | ||
and reduces visual artifacts associated with an abrupt | ||
transition between linear and logarithmic regions of the plot. | ||
rwpenney marked this conversation as resolved. Show resolvedHide resolvedUh oh!There was an error while loading.Please reload this page. | ||
.. note:: | ||
`.scale.AsinhScale` is experimental, and the API may change. | ||
See `~.scale.AsinhScale`, `~.scale.SymmetricalLogScale`. | ||
""" | ||
import numpy as np | ||
import matplotlib.pyplot as plt | ||
# Prepare sample values for variations on y=x graph: | ||
x = np.linspace(-3, 6, 500) | ||
############################################################################### | ||
# Compare "symlog" and "asinh" behaviour on sample y=x graph, | ||
# where there is a discontinuous gradient in "symlog" near y=2: | ||
fig1 = plt.figure() | ||
ax0, ax1 = fig1.subplots(1, 2, sharex=True) | ||
ax0.plot(x, x) | ||
ax0.set_yscale('symlog') | ||
ax0.grid() | ||
ax0.set_title('symlog') | ||
ax1.plot(x, x) | ||
ax1.set_yscale('asinh') | ||
ax1.grid() | ||
ax1.set_title('asinh') | ||
############################################################################### | ||
# Compare "asinh" graphs with different scale parameter "linear_width": | ||
fig2 = plt.figure(constrained_layout=True) | ||
axs = fig2.subplots(1, 3, sharex=True) | ||
rwpenney marked this conversation as resolved. Show resolvedHide resolvedUh oh!There was an error while loading.Please reload this page. | ||
for ax, (a0, base) in zip(axs, ((0.2, 2), (1.0, 0), (5.0, 10))): | ||
ax.set_title('linear_width={:.3g}'.format(a0)) | ||
ax.plot(x, x, label='y=x') | ||
ax.plot(x, 10*x, label='y=10x') | ||
ax.plot(x, 100*x, label='y=100x') | ||
ax.set_yscale('asinh', linear_width=a0, base=base) | ||
ax.grid() | ||
ax.legend(loc='best', fontsize='small') | ||
############################################################################### | ||
# Compare "symlog" and "asinh" scalings | ||
rwpenney marked this conversation as resolved. Show resolvedHide resolvedUh oh!There was an error while loading.Please reload this page. | ||
# on 2D Cauchy-distributed random numbers, | ||
# where one may be able to see more subtle artifacts near y=2 | ||
# due to the gradient-discontinuity in "symlog": | ||
fig3 = plt.figure() | ||
ax = fig3.subplots(1, 1) | ||
r = 3 * np.tan(np.random.uniform(-np.pi / 2.02, np.pi / 2.02, | ||
size=(5000,))) | ||
th = np.random.uniform(0, 2*np.pi, size=r.shape) | ||
ax.scatter(r * np.cos(th), r * np.sin(th), s=4, alpha=0.5) | ||
ax.set_xscale('asinh') | ||
ax.set_yscale('symlog') | ||
ax.set_xlabel('asinh') | ||
ax.set_ylabel('symlog') | ||
ax.set_title('2D Cauchy random deviates') | ||
ax.set_xlim(-50, 50) | ||
ax.set_ylim(-50, 50) | ||
ax.grid() | ||
plt.show() | ||
############################################################################### | ||
# | ||
# .. admonition:: References | ||
# | ||
# - `matplotlib.scale.AsinhScale` | ||
# - `matplotlib.ticker.AsinhLocator` | ||
# - `matplotlib.scale.SymmetricalLogScale` |
Uh oh!
There was an error while loading.Please reload this page.