我知道有点晚了,但我遇到了类似的问题并解决了它,所以我想分享一下解决方案,可以参考matplotlib文档中的custom scale example:
import numpy as np
import scipy.stats as stats
from matplotlib import scale as mscale
from matplotlib import transforms as mtransforms
from matplotlib.ticker import Formatter, FixedLocator
class PPFScale(mscale.ScaleBase):
name = 'ppf'
def __init__(self, axis, **kwargs):
mscale.ScaleBase.__init__(self)
def get_transform(self):
return self.PPFTransform()
def set_default_locators_and_formatters(self, axis):
class VarFormatter(Formatter):
def __call__(self, x, pos=None):
return f'{x}'[1:]
axis.set_major_locator(FixedLocator(np.array([.001,.01,.1,.2,.3,.4,.5,.6,.7,.8,.9,.99,.999])))
axis.set_major_formatter(VarFormatter())
def limit_range_for_scale(self, vmin, vmax, minpos):
return max(vmin, 1e-6), min(vmax, 1-1e-6)
class PPFTransform(mtransforms.Transform):
input_dims = output_dims = 1
def ___init__(self, thresh):
mtransforms.Transform.__init__(self)
def transform_non_affine(self, a):
return stats.norm.ppf(a)
def inverted(self):
return PPFScale.IPPFTransform()
class IPPFTransform(mtransforms.Transform):
input_dims = output_dims = 1
def transform_non_affine(self, a):
return stats.norm.cdf(a)
def inverted(self):
return PPFScale.PPFTransform()
mscale.register_scale(PPFScale)
if __name__ == '__main__':
import matplotlib.pyplot as plt
mu, sigma = 3., 1.
data = np.random.lognormal(mu, sigma, 10000)
dataSorted = np.sort(data)
dataCdf = np.linspace(0,1,len(dataSorted))
plt.plot(dataCdf, dataSorted)
plt.gca().set_xscale('ppf')
plt.gca().set_yscale('log')
plt.xlabel('probability')
plt.ylabel('value')
plt.xlim(0.001,0.999)
plt.grid()
plt.show()
![output[2]](https://istack.dev59.com/yLZd4.webp)
您可能也想看一下我的对数正态分布演示。
plt.gca().set_yscale('log')
->plt.gca().set_xscale('log')
- Chris Mueller