首页 > 解决方案 > 试图在 matplotlib 中创建一个立方 ScaleBase 类,但我无法让它工作。有任何想法吗?

问题描述

我对一些我试图绘制的数据应用了立方变换。由于 matplotlib 没有内置的立方比例尺,我正在尝试使用一个ScaleBase类来创建一个。

我使用这两个示例作为参考(示例 1示例 2),但是在为我计划的立方比例修改这些示例之后,我无法让它工作。ScaleBase无论出于何种原因,我的代码中的类CubedScale对情节没有影响。我将在下面显示两个图,一个没有CubedScale,一个有。

没有应用我的课程的情节CubedScale

plt.plot(np.cbrt(np.arange(0,9)))
plt.show();

创建CubedScale类的代码:

import matplotlib.transforms as transforms
import matplotlib.ticker as ticker
import matplotlib.scale as mscale
import matplotlib.pyplot as plt
import numpy as np

class CubedScale(mscale.ScaleBase):
'''
ScaleBase class for generating cubed scale.
'''

name = 'cubed'

def __init__(self, axis, **kwargs):
    mscale.ScaleBase.__init__(self, axis)
    
def set_default_locators_and_formatters(self, axis):
    axis.set_major_locator(ticker.AutoLocator())
    axis.set_major_formatter(ticker.ScalarFormatter())
    axis.set_minor_locator(ticker.NullLocator())
    axis.set_minor_formatter(ticker.NullFormatter())

def limit_range_for_scale(self, vmin, vmax, minpos):
    return max(0., vmin), vmax

class CubedTransform(mtransforms.Transform):
    input_dims = 1
    output_dims = 1
    is_separable = True
    
    def transform(self, a):
        return np.array(a)**3
    
    def inverted(self): 
        return CubedScale.InvertedCubedTransform()
    
class InvertedCubedTransform(mtransforms.Transform):
    input_dims = 1
    output_dims = 1
    is_separable = True
    
    def transform(self, a):
        return np.cbrt(np.array(a))
    
    def inverted(self):
        return CubedScale.CubedTransform()

def get_transform(self):
    return self.CubedTransform()

mscale.register_scale(CubedScale)

申请后的情节CubedScale

plt.plot(np.cbrt(np.arange(0,9)))
plt.gca().set_yscale('cubed')
ax.set_yticks(np.arange(0,9)**(1/3))
plt.show();

在此处输入图像描述

因此,您可以在此处看到CubedScale已成功创建,但确实可以转换比例。有任何想法吗?提前致谢。

标签: pythonmatplotlib

解决方案


找到的解决方案:

在这里创建一个新ScaleBase类是不必要且麻烦的。

相反,我们可以使用andFuncScale的 'function' 选项。您可以在 matplotlib 文档中参考此示例。set_xscaleset_yscale

这是最终工作的代码和结果图:

import matplotlib.ticker as ticker

def forward(x):
    return x**3

def inverse(x):
    return np.sign(x) * (np.abs(x)) ** (1 / 3)

fig, ax = plt.subplots(1,1)
ax.plot(np.cbrt(np.arange(0,9)))
ax.set_yscale('function', functions=(forward, inverse))
ax.yaxis.set_major_locator(FixedLocator(np.arange(0, 10, 1)**(1/3)))

这就是我试图在操作中实现的目标。y 轴的立方变换。


推荐阅读