Python/Matplotlib - Is there a way to make a discontinuous axis?

后端 未结 5 698
春和景丽
春和景丽 2020-11-22 07:46

I\'m trying to create a plot using pyplot that has a discontinuous x-axis. The usual way this is drawn is that the axis will have something like this:

(values)----/

5条回答
  •  我寻月下人不归
    2020-11-22 08:16

    I see many suggestions for this feature but no indication that it's been implemented. Here is a workable solution for the time-being. It applies a step-function transform to the x-axis. It's a lot of code, but it's fairly simple since most of it is boilerplate custom scale stuff. I have not added any graphics to indicate the location of the break, since that is a matter of style. Good luck finishing the job.

    from matplotlib import pyplot as plt
    from matplotlib import scale as mscale
    from matplotlib import transforms as mtransforms
    import numpy as np
    
    def CustomScaleFactory(l, u):
        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
                lower = l
                upper = u
                def __init__(self, thresh):
                    mtransforms.Transform.__init__(self)
                    self.thresh = thresh
    
                def transform(self, a):
                    aa = a.copy()
                    aa[a>self.lower] = a[a>self.lower]-(self.upper-self.lower)
                    aa[(a>self.lower)&(aself.lower] = a[a>self.lower]+(self.upper-self.lower)
                    return aa
    
                def inverted(self):
                    return CustomScale.CustomTransform(self.thresh)
    
        return CustomScale
    
    mscale.register_scale(CustomScaleFactory(1.12, 8.88))
    
    x = np.concatenate((np.linspace(0,1,10), np.linspace(9,10,10)))
    xticks = np.concatenate((np.linspace(0,1,6), np.linspace(9,10,6)))
    y = np.sin(x)
    plt.plot(x, y, '.')
    ax = plt.gca()
    ax.set_xscale('custom')
    ax.set_xticks(xticks)
    plt.show()
    

    enter image description here

提交回复
热议问题