2017-07-25 76 views
0

我正在使用Python在同一圖上繪製幾條直線。 我在x值上有很大的值變化(在我的代碼中用變量q調用),所以我想將它們放在x軸上相同的距離上,以便在第一部分圖表。如何把不同的幅度值在x軸上相同的距離

這裏我的代碼:

def c(m,x): 
''' 
Linear cost function, describing costs for each weight range 
:param m: the slope, modelling rates 
:param x: the abscissa, modelling quantity ordered 
:return: the cost value for each quantity 
''' 
    return 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.show() 

爲了簡單起見,這裏沒有參與我的代碼片段的所有數據:

enter image description here

正如你所看到的,這是經典數量折扣研究。 所以,如果我只是描繪出這些價值觀,我無法分辨什麼是發生在第一直線,因爲小空間被保留到第一的Q值,見下圖:

enter image description here

現在我秀您在第一q值的放大圖:

enter image description here

我曾經想過是繪製在同一距離的所有q[]值解決辦法:看後面的圖像。 enter image description here 所以我想要實現的僅僅是在x軸上具有相同距離的所有q []值,與它們的值無關。我怎樣才能做到這一點?

+0

謝謝。我編輯了我的問題。 – Bernheart

+0

使用像你展示的軸是可能的,但是直線不會再是直線(它們會彎曲和/或扭曲)。也許你首先要檢查對數縮放是否在正確的方向爲你想要的('plt.gca().set_xscale(「log」,nonposx ='clip')')。 – ImportanceOfBeingErnest

+0

如果我沒有錯,他們應該保持直線,因爲將執行單軸上的線性變換。我只是希望X軸上的每個區間具有相同的長度(對於區間[0,0.1]爲2釐米,區間[100,250]爲2釐米)。 順便說一句,感謝您的幫助 – Bernheart

回答

0

正如在評論中所說的那樣,當操縱刻度以顯示不均勻的間距時,直線將不再是直線。

下面是一個代碼,它在問題中實現了所需的規模。

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() 

enter image description here

從線扭結,這可能是不期望

除此之外,而是從一種這裏使用規模的必然結果,在y軸上的值仍然相當不可讀。

相關問題