2017-04-18 55 views
2

我試圖用math.log(1 + x)而不是通常的'log'縮放選項來縮放圖的x軸,並且我查看了一些自定義縮放的例子,但我不能讓我的工作!這裏是我的MWE:matplotlib中的自定義對數軸縮放

import matplotlib.pyplot as plt 
import numpy as np 
import math 
from matplotlib.ticker import FormatStrFormatter 
from matplotlib import scale as mscale 
from matplotlib import transforms as mtransforms 

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 

     def __init__(self, thresh): 
      mtransforms.Transform.__init__(self) 
      self.thresh = thresh 

     def transform_non_affine(self, a): 
      return math.log(1+a) 

     def inverted(self): 
      return CustomScale.InvertedCustomTransform(self.thresh) 

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

     def __init__(self, thresh): 
      mtransforms.Transform.__init__(self) 
      self.thresh = thresh 

     def transform_non_affine(self, a): 
      return math.log(1+a) 

     def inverted(self): 
      return CustomScale.CustomTransform(self.thresh) 

# Now that the Scale class has been defined, it must be registered so 
# that ``matplotlib`` can find it. 
mscale.register_scale(CustomScale) 

z = [0,0.1,0.3,0.9,1,2,5] 
thick = [20,40,20,60,37,32,21] 

fig = plt.figure(figsize=(8,5)) 
ax1 = fig.add_subplot(111) 
ax1.plot(z, thick, marker='o', linewidth=2, c='k') 

plt.xlabel(r'$\rm{redshift}$', size=16) 
plt.ylabel(r'$\rm{thickness\ (kpc)}$', size=16) 
plt.gca().set_xscale('custom') 
plt.show() 
+0

注意,在matplotlib通常的數標尺使用基座10'math.log()的對數'限定的自然對數(以e爲底的)。你可能想要更清楚一點,你要使用哪個對數。 – ImportanceOfBeingErnest

+0

糟糕,你是對的。我的意思是math.log10! – Arnold

回答

2

規模由兩個變換類,每一類都需要提供transform_non_affine方法。一類需要從數據轉換到顯示座標,這將是log(a+1),另一類是反轉,並且需要從顯示轉換爲數據座標,在這種情況下將是exp(a)-1

這些方法需要處理numpy數組,所以它們應該使用相應的numpy函數而不是數學包中的函數。

class CustomTransform(mtransforms.Transform): 
    .... 

    def transform_non_affine(self, a): 
     return np.log(1+a) 

class InvertedCustomTransform(mtransforms.Transform): 
    .... 

    def transform_non_affine(self, a): 
     return np.exp(a)-1 

enter image description here

+0

完美!非常感謝你的超清晰解釋! – Arnold