Skip to content

Suspected incorrect axis transformation of symlog #7008

Closed as not planned
Closed as not planned
@desert0616

Description

@desert0616

Hi, @mdboom.
Can you roughly explain the meaning of _linscale_adj in SymmetricalLogTransform which was introduced via d8bf0fed4d62324489ffe1d21d114c87ae9ca6a4?


class SymmetricalLogTransform(Transform):
    input_dims = 1
    output_dims = 1
    is_separable = True
    has_inverse = True

    def __init__(self, base, linthresh, linscale):
        Transform.__init__(self)
        self.base = base
        self.linthresh = linthresh
        self.linscale = linscale
        self._linscale_adj = (linscale / (1.0 - self.base ** -1))
        self._log_base = np.log(base)

I am quite puzzled by it.

According to the documentation about linscalex / linscaley, its value is the number of decades to use for each half of the linear range. For example, when linscale == 1.0 (the default), the space used for the positive and negative halves of the linear range will be equal to one decade in the logarithmic range.

As I understand it, it means that when the base is 10 and the linthresh equals to 1, the length of the interval between 0 and 1 should equal to the interval between 1(10^0) and 10(10^1). And this feature seems to be very useful that user can adjust the relative ratio between linear range and logarithmic range.

However, since the _linscale_adj amplifies the original linscale by 1/(1-1/base), the actual place for the linear range will be 1.11x compared to logarithmic range per decade.

For example,


import numpy as np
import matplotlib.pyplot as plt

x = np.array([0, 1, 5, 10, 100, 1000])
y = np.array([0] * 6)

plt.scatter(x, y)
plt.xscale('symlog', linthreshx=10, basex=10, linscalex=1)
plt.grid(True)
plt.show()

base10

If the base is set to 2, the linear range will be 2x than logarithmic range per decade and this issue may be more considerable:


import numpy as np
import matplotlib.pyplot as plt

x = np.array([0, 0.5, 1, 2, 4, 8, 16])
y = np.array([0] * 7)

plt.scatter(x, y)
plt.xscale('symlog', linthreshx=2, basex=2, linscalex=1)
plt.grid(True)
plt.show()

base2

Since _linscale_adj is relatively independent and is only used to be a coefficient of transformation for symlog, it seems not to be a bug. So, what is the meaning of the scaling of _linscale_adj which related to its base?

Well, as a user, the figures showed above is very weird and I used to set the linscale manually to 0.9 (base=10) to make each tick interval to be equal.

Thanks.

Metadata

Metadata

Assignees

No one assigned

    Labels

    status: closed as inactiveIssues closed by the "Stale" Github Action. Please comment on any you think should still be open.status: inactiveMarked by the “Stale” Github Action

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions