具有不同因子和bas的对数标度

2024-05-23 14:20:46 发布

您现在位置:Python中文网/ 问答频道 /正文

我看到set_xscale接受一个base参数,但我也想用一个因子进行缩放;也就是说,如果基数是4,因子是10,那么:

40, 160, 640, ...

另外,文档中说由subsx表示的子网格值应该是整数,但我需要浮点值。你知道吗

最干净的方法是什么?你知道吗


Tags: 方法文档网格base参数整数因子浮点
1条回答
网友
1楼 · 发布于 2024-05-23 14:20:46

我不知道有什么内置方法可以在指数之后应用缩放因子,但是您可以通过子类化^{}^{}来创建自定义记号定位器和格式化程序。你知道吗

下面是一个相当快速和肮脏的黑客,它可以满足您的要求:

from matplotlib import pyplot as plt
from matplotlib.ticker import LogLocator, LogFormatter, ScalarFormatter, \
                              is_close_to_int, nearest_long
import numpy as np
import math

class ScaledLogLocator(LogLocator):
    def __init__(self, *args, scale=10.0, **kwargs):
        self._scale = scale
        LogLocator.__init__(self, *args, **kwargs)

    def view_limits(self, vmin, vmax):
        s = self._scale
        vmin, vmax = LogLocator.view_limits(self, vmin / s, vmax / s)
        return s * vmin, s * vmax

    def tick_values(self, vmin, vmax):
        s = self._scale
        locs = LogLocator.tick_values(self, vmin / s, vmax / s)
        return s * locs

class ScaledLogFormatter(LogFormatter):
    def __init__(self, *args, scale=10.0, **kwargs):
        self._scale = scale
        LogFormatter.__init__(self, *args, **kwargs)

    def __call__(self, x, pos=None):
        b = self._base
        s = self._scale

        # only label the decades
        if x == 0:
            return '$\mathdefault{0}$'

        fx = math.log(abs(x / s)) / math.log(b)
        is_decade = is_close_to_int(fx)
        sign_string = '-' if x < 0 else ''

        # use string formatting of the base if it is not an integer
        if b % 1 == 0.0:
            base = '%d' % b
        else:
            base = '%s' % b
        scale = '%d' % s

        if not is_decade and self.labelOnlyBase:
            return ''
        elif not is_decade:
            return ('$\mathdefault{%s%s\times%s^{%.2f}}$'
                     % (sign_string, scale, base, fx))
        else:
            return (r'$%s%s\times%s^{%d}$'
                    % (sign_string, scale, base, nearest_long(fx)))

例如:

fig, ax = plt.subplots(1, 1)
x = np.arange(1000)
y = np.random.randn(1000)
ax.plot(x, y)
ax.set_xscale('log')
subs = np.linspace(0, 1, 10)

majloc = ScaledLogLocator(scale=10, base=4)
minloc = ScaledLogLocator(scale=10, base=4, subs=subs)
fmt = ScaledLogFormatter(scale=10, base=4)
ax.xaxis.set_major_locator(majloc)
ax.xaxis.set_minor_locator(minloc)
ax.xaxis.set_major_formatter(fmt)
ax.grid(True)

# show the same tick locations with non-exponential labels
ax2 = ax.twiny()
ax2.set_xscale('log')
ax2.set_xlim(*ax.get_xlim())
fmt2 = ScalarFormatter()
ax2.xaxis.set_major_locator(majloc)
ax2.xaxis.set_minor_locator(minloc)
ax2.xaxis.set_major_formatter(fmt2)

enter image description here

相关问题 更多 >