Python matplotlib 3.0.3中未使用自定义比例显示刻度

Python matplotlib 3.0.3中未使用自定义比例显示刻度,python,matplotlib,Python,Matplotlib,我编写了以下自定义比例类: import numpy as np from matplotlib import scale as mscale from matplotlib import transforms as mtransforms from matplotlib.ticker import Formatter class PiecewiseLinearScale(mscale.ScaleBase): name = 'piecewise' def __init__(s

我编写了以下自定义比例类:

import numpy as np
from matplotlib import scale as mscale
from matplotlib import transforms as mtransforms
from matplotlib.ticker import Formatter

class PiecewiseLinearScale(mscale.ScaleBase):
    name = 'piecewise'

    def __init__(self, axis, *, thresholds=None, true_values=None, **kwargs):
        mscale.ScaleBase.__init__(self)
        if thresholds is None:
            thresholds = [0, 1, 3, 5, 10]
        if true_values is None:
            true_values = [0, 1, 2, 3, 4]
        if len(thresholds) != len(true_values):
            raise ValueError("thresholds and true_values should have the same length")
        tp = thresholds[0]
        for t in thresholds[1:]:
            if t <= tp:
                raise ValueError("Values in thresholds array should be ascending")
            t = tp

        tp = true_values[0]
        for t in true_values[1:]:
            if t <= tp:
                raise ValueError("Values in true_values array should be ascending")
            t = tp
        self.thresholds = thresholds
        self.true_values = true_values

    def get_transform(self):
        return self.PiecewiseLinearLatitudeTransform(self.thresholds, self.true_values)

    def set_default_locators_and_formatters(self, axis):
        class DegreeFormatter(Formatter):
            def __call__(self, x, pos=None):
                return "{}".format(x)

        axis.set_major_formatter(DegreeFormatter())
        axis.set_minor_formatter(DegreeFormatter())

    def limit_range_for_scale(self, vmin, vmax, minpos):
        return max(vmin, self.true_values[0]), min(vmax, self.true_values[-1])

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

        def __init__(self, thresholds = None, true_values = None):
            mtransforms.Transform.__init__(self)
            if thresholds is None:
                thresholds = [0, 1, 3, 5, 10]
            if true_values is None:
                true_values = [0, 1, 2, 3, 4]
            self.true_values = true_values
            self.thresholds = thresholds

        def transform_non_affine(self, a):
            masked = np.ma.masked_where((a < self.true_values[0]) | (a > self.true_values[-1]), a)
            # val = None
            proper_stuff = []
            for val in masked:
                if isinstance(val, np.ma.core.MaskedConstant):
                    proper_stuff.append(np.ma.core.MaskedConstant())
                    continue
                for i, t_v in enumerate(self.true_values[1:]):
                    if t_v >= val:
                        proper_true_ind = i
                        break
                else:
                    proper_true_ind = i
                unbiased = val-self.true_values[proper_true_ind]

                true_values_raise = self.true_values[proper_true_ind+1] - self.true_values[proper_true_ind]
                thresholds_raise = self.thresholds[proper_true_ind+1] - self.thresholds[proper_true_ind]

                first_part = unbiased/true_values_raise
                unbiased_scaled = first_part*thresholds_raise

                proper_stuff.append(self.thresholds[proper_true_ind] + unbiased_scaled)

            return np.ma.array(proper_stuff)

        def inverted(self):
            return PiecewiseLinearScale.InvertedPiecewiseLinearLatitudeTransform(
                self.thresholds, self.true_values)

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

        def __init__(self, thresholds = None, true_values = None):
            mtransforms.Transform.__init__(self)
            if thresholds is None:
                thresholds = [0, 1, 3, 5, 10]
            if true_values is None:
                true_values = [0, 1, 2, 3, 4]
            self.true_values = true_values
            self.thresholds = thresholds

        def transform_non_affine(self, a):
            masked = np.ma.masked_where((a < self.thresholds[0]) | (a > self.thresholds[-1]), a)
            proper_stuff = []
            for val in masked:
                if isinstance(val, np.ma.core.MaskedConstant):
                    proper_stuff.append(np.ma.core.MaskedConstant())
                    continue
                for i, t_v in enumerate(self.thresholds[1:]):
                    if t_v >= val:
                        proper_true_ind = i
                        break
                    else:
                        proper_true_ind = i
                true_values_raise = self.true_values[proper_true_ind+1] - self.true_values[proper_true_ind]
                thresholds_raise = self.thresholds[proper_true_ind+1] - self.thresholds[proper_true_ind]

                unbiased = val-self.thresholds[proper_true_ind]
                proper_stuff.append(self.true_values[proper_true_ind] + unbiased*true_values_raise/thresholds_raise)
            return np.ma.array(proper_stuff)

        def inverted(self):
            return PiecewiseLinearScale.PiecewiseLinearLatitudeTransform(self.thresholds, self.true_values)


我更喜欢解决方案/建议,它只更改第一个代码块。

因此,经过一点调试之后

我发现,将屏蔽值放入从
InvertedPiecewiseLinearatitudeTransform
变换非仿射方法返回的数组中是错误的想法-我应该使用
np.nan
。更改后的代码现在如下所示:

def transform_non_affine(self, a):
    masked = a.copy()
    masked[(a < self.thresholds[0]) | (a > self.thresholds[-1])] = np.nan
    proper_stuff = []
    for val in masked:
        if isinstance(val, np.ma.core.MaskedConstant):
            proper_stuff.append(np.ma.core.MaskedConstant())
            continue
        for i, t_v in enumerate(self.thresholds[1:]):
            if t_v >= val:
                proper_true_ind = i
                break
            else:
                proper_true_ind = i
        true_values_raise = self.true_values[proper_true_ind+1] - self.true_values[proper_true_ind]
        thresholds_raise = self.thresholds[proper_true_ind+1] - self.thresholds[proper_true_ind]

        unbiased = val-self.thresholds[proper_true_ind]
        proper_stuff.append(self.true_values[proper_true_ind] + unbiased*true_values_raise/thresholds_raise)
    res = np.array(proper_stuff)
    return res
def变换非仿射(self,a):
蒙版=a.copy()
蒙版[(aself.thresholds[-1])]=np.nan
正确的东西=[]
对于遮罩中的val:
如果isinstance(val,np.ma.core.MaskedConstant):
property_stuff.append(np.ma.core.MaskedConstant())
持续
对于枚举中的i,t_v(self.thresholds[1:]):
如果t_v>=val:
正确的\u正确的\u ind=i
打破
其他:
正确的\u正确的\u ind=i
真值提升=self.真值[property\u true\u ind+1]-真值[property\u true\u ind]
阈值提升=自阈值[property\u true\u ind+1]-自阈值[property\u true\u ind]
无偏=值自身阈值[正确值]
property\u stuff.append(self.true\u values[property\u true\u ind]+无偏*true\u values\u raise/thresholds\u raise)
res=np.数组(适当的东西)
返回res
def transform_non_affine(self, a):
    masked = a.copy()
    masked[(a < self.thresholds[0]) | (a > self.thresholds[-1])] = np.nan
    proper_stuff = []
    for val in masked:
        if isinstance(val, np.ma.core.MaskedConstant):
            proper_stuff.append(np.ma.core.MaskedConstant())
            continue
        for i, t_v in enumerate(self.thresholds[1:]):
            if t_v >= val:
                proper_true_ind = i
                break
            else:
                proper_true_ind = i
        true_values_raise = self.true_values[proper_true_ind+1] - self.true_values[proper_true_ind]
        thresholds_raise = self.thresholds[proper_true_ind+1] - self.thresholds[proper_true_ind]

        unbiased = val-self.thresholds[proper_true_ind]
        proper_stuff.append(self.true_values[proper_true_ind] + unbiased*true_values_raise/thresholds_raise)
    res = np.array(proper_stuff)
    return res