What is the difference between 'log' and 'symlog'?
Asked Answered
L

3

136

In matplotlib, I can set the axis scaling using either pyplot.xscale() or Axes.set_xscale(). Both functions accept three different scales: 'linear' | 'log' | 'symlog'.

What is the difference between 'log' and 'symlog'? In a simple test I did, they both looked exactly the same.

I know the documentation says they accept different parameters, but I still don't understand the difference between them. Can someone please explain it? The answer will be the best if it has some sample code and graphics! (also: where does the name 'symlog' come from?)

Leibniz answered 22/7, 2010 at 4:55 Comment(0)
L
239

I finally found some time to do some experiments in order to understand the difference between them. Here's what I discovered:

  • log only allows positive values, and lets you choose how to handle negative ones (mask or clip).
  • symlog means symmetrical log, and allows positive and negative values.
  • symlog allows to set a range around zero within the plot will be linear instead of logarithmic.

I think everything will get a lot easier to understand with graphics and examples, so let's try them:

import numpy
from matplotlib import pyplot

# Enable interactive mode
pyplot.ion()

# Draw the grid lines
pyplot.grid(True)

# Numbers from -50 to 50, with 0.1 as step
xdomain = numpy.arange(-50,50, 0.1)

# Plots a simple linear function 'f(x) = x'
pyplot.plot(xdomain, xdomain)
# Plots 'sin(x)'
pyplot.plot(xdomain, numpy.sin(xdomain))

# 'linear' is the default mode, so this next line is redundant:
pyplot.xscale('linear')

A graph using 'linear' scaling

# How to treat negative values?
# 'mask' will treat negative values as invalid
# 'mask' is the default, so the next two lines are equivalent
pyplot.xscale('log')
pyplot.xscale('log', nonposx='mask')

A graph using 'log' scaling and nonposx='mask'

# 'clip' will map all negative values a very small positive one
pyplot.xscale('log', nonposx='clip')

A graph using 'log' scaling and nonposx='clip'

# 'symlog' scaling, however, handles negative values nicely
pyplot.xscale('symlog')

A graph using 'symlog' scaling

# And you can even set a linear range around zero
pyplot.xscale('symlog', linthreshx=20)

A graph using 'symlog' scaling, but linear within (-20,20)

Just for completeness, I've used the following code to save each figure:

# Default dpi is 80
pyplot.savefig('matplotlib_xscale_linear.png', dpi=50, bbox_inches='tight')

Remember you can change the figure size using:

fig = pyplot.gcf()
fig.set_size_inches([4., 3.])
# Default size: [8., 6.]

(If you are unsure about me answering my own question, read this)

Leibniz answered 18/8, 2010 at 14:29 Comment(3)
The args changed, and now needs to be called with argument "linthresh" instead of "linthreshx" btw.Storfer
Some links to recent documentation: matplotlib.org/stable/api/_as_gen/… matplotlib.org/stable/api/… and matplotlib.org/stable/gallery/scales/…Sinuation
Why is the y-axis limit not adjusted for "clip" or "mask"? See also #77278092Schnapps
P
29

symlog is like log but allows you to define a range of values near zero within which the plot is linear, to avoid having the plot go to infinity around zero.

From http://matplotlib.sourceforge.net/api/axes_api.html#matplotlib.axes.Axes.set_xscale

In a log graph, you can never have a zero value, and if you have a value that approaches zero, it will spike down way off the bottom off your graph (infinitely downward) because when you take "log(approaching zero)" you get "approaching negative infinity".

symlog would help you out in situations where you want to have a log graph, but when the value may sometimes go down towards, or to, zero, but you still want to be able to show that on the graph in a meaningful way. If you need symlog, you'd know.

Participation answered 22/7, 2010 at 4:58 Comment(1)
Well... I read that, but I still don't know when I should use one or another. I was expecting some kind of graphical example so I could actually see what is the problem that symlog tries to solve.Sinuation
P
14

Here's an example of behaviour when symlog is necessary:

Initial plot, not scaled. Notice how many dots cluster at x~0

    ax = sns.scatterplot(x= 'Score', y ='Total Amount Deposited', data = df, hue = 'Predicted Category')

[Non scaled '

Log scaled plot. Everything collapsed.

    ax = sns.scatterplot(x= 'Score', y ='Total Amount Deposited', data = df, hue = 'Predicted Category')

    ax.set_xscale('log')
    ax.set_yscale('log')
    ax.set(xlabel='Score, log', ylabel='Total Amount Deposited, log')

Log scale '

Why did it collapse? Because of some values on the x-axis being very close or equal to 0.

Symlog scaled plot. Everything is as it should be.

    ax = sns.scatterplot(x= 'Score', y ='Total Amount Deposited', data = df, hue = 'Predicted Category')

    ax.set_xscale('symlog')
    ax.set_yscale('symlog')
    ax.set(xlabel='Score, symlog', ylabel='Total Amount Deposited, symlog')

Symlog scale

Pubis answered 20/10, 2019 at 21:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.