2014-10-04 36 views
1

我正在试图用指数(?)Y轴创建一个matplotlib图,就像我在下面嘲笑的那个假的一样。对于我的数据,我想在接近最大Y值时分散这些值。当Y变得接近零时,我想压缩这些值。我该如何用matplotlib按指数函数缩放Y轴

所有正常的“日志”示例都会做相反的事情:当数值远离零时,它们将压缩值。当然,这就是'日志'的作用。我怎样才能创建一个指数(?)缩放?

graph

+0

指数如何? - y轴的缩放功能是什么?为什么日志记录轴不足? – wwii 2014-10-05 02:45:16

+0

我并不确定确切的功能,但我想要一个旋钮,使我能够在Y值如上所述接近零时平滑压缩。我会说10 ** Y但是不确定[0..1]之间的Y.但有了以上的数值,我很关心Y = 10与Y = 9之间的数值。但是例如Y = 5以下的任何东西都不重要。这似乎不是一个疯狂的事情想要吗? – Philip 2014-10-05 11:54:54

+0

不疯狂,我已经看到仪器具有不同范围的缩放比例。这可能需要一些工作,@Tommy建议的方法可以用于缩放值 - 然后您必须弄清楚如何标记轴。你是否通过画廊和“Axes''文档搜索? – wwii 2014-10-05 12:16:58

回答

0

我假设你的意思是X轴的,因为你的模拟图中,X轴是指数,而不是Y轴。

你可以做这样的事情:

... 
ax = plt.subplot(111) 
ax.plot(Xs,Ys,color='blue',linewidth=2) 
.... 
xlabs = [pow(10,i) for i in range(0,6)] 
ax.set_xticklabels(xlabs) 
ax.set_xticks(xlabs) 

什么,我这里做的是手工创建6 x s的列表,其中每个被10^i代表,即10^1,10^2,...。这会将X刻度线标记为正确,并标记为[1, 10, 100, 1000, 10000, 100000]。如果您需要更多标签,请更改6

+0

不,我的意思是Y轴.... X是'记录'在这里,但Y是指数。 X有一个很大的范围和很好的标签,所以很清楚。 Y是指数级,只是标签/网格不好。注意从10.9到9.9相对于9的距离。9至0.9。我希望matplotlib能够像'log'一样按比例缩放我的数据。不仅具有指数间隔的标签。 – Philip 2014-10-05 01:00:40

2

我不认为它是直接可能的。但当然,你总是可以尝试作弊。在我的例子我刚写的东西在别的标签:

import matplotlib.pyplot as plt 
import numpy as np 

x = np.linspace(1, 40, 100); 
y = np.linspace(1, 4, 100); 

# Actually plot the exponential values 
plt.plot(x, np.e**y) 
ax = plt.gca() 

# Set x logaritmic 
ax.set_xscale('log') 

# Rewrite the y labels 
y_labels = np.linspace(min(y), max(y), 4) 
ax.set_yticks(np.e**y_labels) 
ax.set_yticklabels(y_labels) 

plt.show() 

其结果都是: enter image description here

0

Matplotlib文档创建新的轴标可用here

matplotlib目前不包含指数缩放比例,但您可以使用example作为您自己实现的起点。

0

这不完全一般,因为定位器是硬编码为我的情况。但这对我有效。我必须创建一个名为ExponentialScale的新规模,使用基数为1.1的ma.power。太复杂了一个看似简单的事情:

class ExponentialScale(mscale.ScaleBase): 
    name = 'expo' 
    base = 1.1 
    logbase = math.log(base) 

def __init__(self, axis, **kwargs): 
    mscale.ScaleBase.__init__(self) 
    self.thresh = None #thresh 

def get_transform(self): 
    return self.ExponentialTransform(self.thresh) 

def set_default_locators_and_formatters(self, axis): 
    # I could not get LogLocator to do what I wanted. I don't understand 
    # the docs about "subs" and the source was not clear to me. 
    # So I just spell out the lines I want: 
    major = [1, 5, 10, 12, 14, 16, 18, 20, 25, 28, 30] + range(31,60) 
    axis.set_major_locator(ticker.FixedLocator(major)) 

class ExponentialTransform(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): 
     res = ma.power(ExponentialScale.base, a) 
     return res 

    def inverted(self): 
     return ExponentialScale.InvertedExponentialTransform(self.thresh) 

class InvertedExponentialTransform(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): 
     denom = np.repeat(ExponentialScale.logbase, len(a)) 
     return np.log(a)/denom 

    def inverted(self): 
     return ExponentialScale.ExponentialTransform(self.thresh) 
1

只需添加到这个代码日志规模:

plt.figure() 
ax = plt.subplot(111) 
ax.set_yscale('log') 

但是,如果你想有一个指数的规模,这个问题的答案是: link to question

+0

日志是不一样的指数... – Philip 2016-04-22 01:13:34

+0

啊真的,脱脂读取的问题。添加了一个链接,指导如何做到这一点 – mjp 2016-04-23 14:29:53