正如在評論中所說的那樣,當操縱刻度以顯示不均勻的間距時,直線將不再是直線。
下面是一個代碼,它在問題中實現了所需的規模。
import numpy as np
from numpy import ma
from matplotlib import scale as mscale
from matplotlib import transforms as mtransforms
from matplotlib.ticker import FixedLocator
class SegmentedScale(mscale.ScaleBase):
name = 'segmented'
def __init__(self, axis, **kwargs):
mscale.ScaleBase.__init__(self)
self.points = kwargs.get('points',[0,1])
self.lb = self.points[0]
self.ub = self.points[-1]
def get_transform(self):
return self.SegTrans(self.lb, self.ub, self.points)
def set_default_locators_and_formatters(self, axis):
axis.set_major_locator(FixedLocator(self.points))
def limit_range_for_scale(self, vmin, vmax, minpos):
return max(vmin, self.lb), min(vmax, self.ub)
class SegTrans(mtransforms.Transform):
input_dims = 1
output_dims = 1
is_separable = True
def __init__(self, lb, ub, points):
mtransforms.Transform.__init__(self)
self.lb = lb
self.ub = ub
self.points = points
def transform_non_affine(self, a):
masked = a # ma.masked_where((a < self.lb) | (a > self.ub), a)
return np.interp(masked, self.points, np.arange(len(self.points)))
def inverted(self):
return SegmentedScale.InvertedSegTrans(self.lb, self.ub, self.points)
class InvertedSegTrans(SegTrans):
def transform_non_affine(self, a):
return np.interp(a, np.arange(len(self.points)), self.points)
def inverted(self):
return SegmentedScale.SegTrans(self.lb, self.ub, self.points)
# Now that the Scale class has been defined, it must be registered so
# that ``matplotlib`` can find it.
mscale.register_scale(SegmentedScale)
if __name__ == '__main__':
u= u"""0, 137.13, 0.082
0.1, 112.46, 0.175
0.2, 98.23, 0.368
0.5, 72.38, 0.838
1, 60.69, 8.932
10, 54.21, 17.602
20, 47.71, 48.355
50, 46.14, 89.358
100, 41.23, 241.147
250, 39.77, 0"""
import io
import matplotlib.pyplot as plt
q,r,breakpoints = np.loadtxt(io.StringIO(u), delimiter=", ", unpack=True)
c = lambda m,x : m*x
for i in range(0,9):
w = np.arange(0., q[9], 0.01)
plt.plot(w,c(r[i],w),'b--',linewidth=0.3)
plt.plot([q[i],breakpoints[i]] , [c(r[i], q[i]), c(r[i], breakpoints[i])], 'r')
plt.plot(q[i + 1], c(r[i], breakpoints[i]), 'r.')
plt.gca().set_xscale('segmented', points = q)
plt.show()
從線扭結,這可能是不期望
除此之外,而是從一種這裏使用規模的必然結果,在y軸上的值仍然相當不可讀。
謝謝。我編輯了我的問題。 – Bernheart
使用像你展示的軸是可能的,但是直線不會再是直線(它們會彎曲和/或扭曲)。也許你首先要檢查對數縮放是否在正確的方向爲你想要的('plt.gca().set_xscale(「log」,nonposx ='clip')')。 – ImportanceOfBeingErnest
如果我沒有錯,他們應該保持直線,因爲將執行單軸上的線性變換。我只是希望X軸上的每個區間具有相同的長度(對於區間[0,0.1]爲2釐米,區間[100,250]爲2釐米)。 順便說一句,感謝您的幫助 – Bernheart