2017-04-18 26 views
2

私はプロットのx軸を、通常の 'log'スケールオプションの代わりにmath.log(1 + 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方法を提供する必要があり、それぞれが2つの変換のクラスで構成されています。 1つのクラスは、log(a+1)になるデータから表示座標に変換する必要があり、もう1つは逆であり、ディスプレイからデータ座標に変換する必要があります。この場合はexp(a)-1となります。

これらのメソッドはnumpy配列を扱う必要があるので、mathパッケージの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