Jaka jest różnica między „log” a „symlog”?

101

W matplotlib mogę ustawić skalowanie osi za pomocą albo pyplot.xscale()lub Axes.set_xscale(). Obie funkcje akceptują trzy różne skale: 'linear'| 'log'| 'symlog'.

Jaka jest różnica między 'log'i 'symlog'? W prostym teście, który przeprowadziłem, obaj wyglądali dokładnie tak samo.

Wiem, że dokumentacja mówi, że akceptują różne parametry, ale nadal nie rozumiem różnicy między nimi. Czy ktoś może to wyjaśnić? Odpowiedź będzie najlepsza, jeśli będzie zawierał przykładowy kod i grafikę! (też: skąd się wzięła nazwa „symlog”?)

Denilson Sá Maia
źródło

Odpowiedzi:

188

W końcu znalazłem trochę czasu na kilka eksperymentów, aby zrozumieć różnicę między nimi. Oto, co odkryłem:

  • logdopuszcza tylko wartości dodatnie i pozwala wybrać sposób obsługi ujemnych ( masklub clip).
  • symlogoznacza logarytm symetryczny i dopuszcza wartości dodatnie i ujemne.
  • symlog pozwala na ustawienie zakresu wokół zera w obrębie wykresu będzie liniowa zamiast logarytmiczna.

Myślę, że dzięki grafikom i przykładom wszystko będzie o wiele łatwiejsze do zrozumienia, więc wypróbujmy je:

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')

Wykres wykorzystujący skalowanie „liniowe”

# 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')

Wykres wykorzystujący skalowanie „log” i nonposx = „maska”

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

Wykres wykorzystujący skalowanie „log” i nonposx = „clip”

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

Wykres wykorzystujący skalowanie „symlog”

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

Wykres wykorzystujący skalowanie „symlog”, ale liniowy w granicach (-20,20)

Dla kompletności użyłem następującego kodu, aby zapisać każdą figurę:

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

Pamiętaj, że możesz zmienić rozmiar figury za pomocą:

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

(Jeśli nie masz pewności, czy odpowiadam na własne pytanie, przeczytaj to )

Denilson Sá Maia
źródło
19

symlog jest podobny do log, ale umożliwia zdefiniowanie zakresu wartości bliskich zeru, w których wykres jest liniowy, aby uniknąć sytuacji, w której wykres osiąga nieskończoność w okolicy zera.

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

Na wykresie logarytmicznym nigdy nie możesz mieć wartości zerowej, a jeśli masz wartość zbliżoną do zera, będzie ona gwałtownie spadać w dół wykresu (nieskończenie w dół), ponieważ kiedy weźmiesz „log (zbliżanie się do zera)”, uzyskać „zbliżanie się do ujemnej nieskończoności”.

symlog pomoże ci w sytuacjach, w których chcesz mieć wykres log, ale kiedy wartość może czasami spaść do zera lub do zera, ale nadal chcesz mieć możliwość pokazania tego na wykresie w znaczący sposób. Jeśli potrzebujesz symlogu, wiesz.

thomasrutter
źródło
Cóż ... Czytałem to, ale nadal nie wiem, kiedy powinienem użyć jednego lub drugiego. Spodziewałem się jakiegoś przykładu graficznego, żeby zobaczyć, jaki problem próbuje rozwiązać symlog .
Denilson Sá Maia
4

Oto przykład zachowania, gdy symlog jest konieczny:

Działka początkowa, nie skalowana. Zwróć uwagę, ile punktów skupia się na x ~ 0

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

[ Nie skalowane '

Wykres ze skalą dziennika. Wszystko się zawaliło.

    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')

Skala logarytmiczna '

Dlaczego się zawalił? Ponieważ niektóre wartości na osi X są bardzo bliskie lub równe 0.

Wykres skalowany Symlog. Wszystko jest tak, jak powinno.

    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')

Skala Symlog

Gigikalo
źródło