如何生成指数缩放的坐标轴?

7 投票
2 回答
4968 浏览
提问于 2025-04-16 11:14

考虑以下代码:

from numpy import log2
import matplotlib.pyplot as plt

xdata = [log2(x)*(10/log2(10)) for x in range(1,11)]
ydata = range(10)
plt.plot(xdata, ydata)
plt.show()

这段代码生成了下面这个图:我不想要的图 我的问题是,如何修改这段代码,让图看起来是一条直线,尽管输入的数据完全一样?这其实是需要适当地调整x轴的刻度,但我不知道该怎么做。这样做的原因是,我要展示一个在开始时变化很小,但在有效区间的后面开始波动更大的函数,所以我想在后面部分有更高的水平分辨率。如果有人能提出其他解决方案,也欢迎分享!

2 个回答

2

最简单的方法是使用 semilogy

from numpy import log2
import matplotlib.pyplot as plt

xdata = log2(range(1,11)) * (10/log2(10))
ydata = range(10)
plt.semilogy(xdata, ydata)
plt.show()

在这里输入图片描述

7

这里有一个实现方法。你可以参考一个很好的示例。你只需要创建一个ScaleBase类的子类。

这是你的转换过程。其实当你去掉所有自定义格式和其他复杂的东西后,它并不太复杂。只是稍微有点啰嗦。

from numpy import log2
import matplotlib.pyplot as plt

from matplotlib import scale as mscale
from matplotlib import transforms as mtransforms

class CustomScale(mscale.ScaleBase):
    name = 'custom'

    def __init__(self, axis, **kwargs):
        mscale.ScaleBase.__init__(self)
        self.thresh = None #thresh

    def get_transform(self):
        return self.CustomTransform(self.thresh)

    def set_default_locators_and_formatters(self, axis):
        pass

    class CustomTransform(mtransforms.Transform):
        input_dims = 1
        output_dims = 1
        is_separable = True

        def __init__(self, thresh):
            mtransforms.Transform.__init__(self)
            self.thresh = thresh

        def transform_non_affine(self, a):
            return 10**(a/10)

        def inverted(self):
            return CustomScale.InvertedCustomTransform(self.thresh)

    class InvertedCustomTransform(mtransforms.Transform):
        input_dims = 1
        output_dims = 1
        is_separable = True

        def __init__(self, thresh):
            mtransforms.Transform.__init__(self)
            self.thresh = thresh

        def transform_non_affine(self, a):
            return log2(a)*(10/log2(10))

        def inverted(self):
            return CustomScale.CustomTransform(self.thresh)


mscale.register_scale(CustomScale)

xdata = [log2(x)*(10/log2(10)) for x in range(1,11)]
ydata = range(10)
plt.plot(xdata, ydata)

plt.gca().set_xscale('custom')
plt.show()

撰写回答