Skip to content
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 our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Symmetric Log scale: linscale < 1 ? #2288

Closed
sergey-ns opened this issue Aug 9, 2013 · 7 comments
Closed

Symmetric Log scale: linscale < 1 ? #2288

sergey-ns opened this issue Aug 9, 2013 · 7 comments
Milestone

Comments

@sergey-ns
Copy link

summary

  1. remove limitation linscale>=1.0 in SymmetricLogScale;
  2. set linscale=1.0/math.log(base) or multiply linscale*=1.0/math.log(base) internally

explanation

currently one cannot set linscale values less than 1 in
Axes.set_{x,y}scale
due to
(matplotlib/scale.py:449) assert linscale >= 1.0

Setting linscale=1.0/math.log(base) (which is < 1.0) ensures that the symlog transformation function is smooth, i.e. its derivative is continuous at the border between linear and logarithmic regions. Smoothness of the transformation function is necessary&sufficient to avoid kinks in plots of smooth curves, i.e a smooth curve (with a continuous derivative) will be shown as a smooth curve. (see pictures). It makes sense then to set linscale=1.0/log(base) by default, or multiply it by this appropriate factor internally.

examples

(default)

fig_default

(smooth, generated with patched matplotlib/scale.py sans 'assert linscale >= 1.0')

fig_smooth

(kink)

fig_kink

generated with the following script

import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
import math

x   = np.r_[-1:1:2000j]
y   = 1e2**(-x) - 0.02

# default
ax  = plt.figure().add_axes([0.1, 0.1, 0.8, 0.8])
ax.plot(x, y, ls='-')
ax.set_yscale('symlog')
ax.figure.savefig('fig_default.png')

# smooth
ax  = plt.figure().add_axes([0.1, 0.1, 0.8, 0.8])
ax.plot(x, y, ls='-')
ax.set_yscale('symlog', linscaley=1./math.log(10))
ax.figure.savefig('fig_smooth.png')

# rough
ax  = plt.figure().add_axes([0.1, 0.1, 0.8, 0.8])
ax.plot(x, y, ls='-')
ax.set_yscale('symlog', linscaley=math.log(10))
ax.figure.savefig('fig_kink.png')
@Tillsten
Copy link
Contributor

Tillsten commented May 7, 2014

This should be 1.4 milestone. I will try to solve this tomorrow.

@Tillsten
Copy link
Contributor

Tillsten commented May 7, 2014

To be more exact, i think we should allow linscale to be smaller than 1, does anybody see why this is enforced. For the rest of the issuse: the smoothness depends not only one linscale, but also on linthresh. I also think it is a little bit late to change defaults.

@Tillsten
Copy link
Contributor

Tillsten commented May 7, 2014

It is probably fine to just change the assert to > 0?

@tacaswell tacaswell added this to the v1.4.0 milestone May 7, 2014
@tacaswell
Copy link
Member

milestoned an requested, but did not really read/understand what is going on.

@Tillsten
Copy link
Contributor

Tillsten commented May 7, 2014

linscale defines the space ratio between a decade in the log-plot and halve of the linear part.
I actually need a ratio smaller than 1, else the log-part is to small for my case.

@Tillsten
Copy link
Contributor

Tillsten commented May 7, 2014

pinging @mdboom

@tacaswell
Copy link
Member

Closing as #3053 is merged.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants