我正在做一些通用数据,并将其从电源值转换为db值。由于系统,这些值来自0,0用作“这里的有用数据”指示符(数学的性质,而不是定义的值)。

我通常的处理这些方式是在尝试/之外包装转换,并返回默认的“低”值,例如

def f(value):
    try:
        return convert(value)
    except ValueError:
        return -140 #implementation specific, don't worry
.

这很好,令人垂涎的90%在我的框架内使用,除了绘制时。

我很懒,所以我在分钟内做的是:

pl.plot(xvals,map(f,yvals))
.

这可以正确绘制数据,当数据结束时,从悬崖上伸出悬崖,这是预期的行为。但是,我想发生的是将图形为结束遇到值为valueError异常并且完全消除f()。

除了将地图打成一个循环,任何人都有任何辉煌的想法?

更新:

我正在使用pylab / matplotlib “端点”依赖于执行;有时以上并不重要,因为没有“坏”值。这一切都努力让我懒惰,并使用Matplotlibs图表缩放而不是基于YDATA的最小值(我不做ATM,在这种情况下只能重置动态Ylim。)

答案上模糊的重要更新: Unutbu的答案是我实际使用的是我的实现,因为(问题依赖性未提及),因为在这个定期使用的函数中提高了一个缺陷的函数造成的不相关到逻辑的逻辑,而不会使所有其他实例在预防之外;有时-inf会比你想象的更有意义。

感谢每个人都令人敬畏,我向Unutbu道歉的问号。

有帮助吗?

解决方案

Perhaps there's some trick in the plotting library, but a much better options seems not generating such data to begin with. It's not that map saves you thirty lines of code...

Use itertools.takewhile(lambda y: y != NO_VALUE, (f(y) for y in yvals)) (and wrap it in a call to list if the plotting library requires a list instead of an iterable).

Edit: I had an even better idea: In the wrapper, add

except ValueError:
    raise StopIteration

That's the exception signaling "end of iterale", and map respects it.

其他提示

If you are using matplotlib, then it implies you have numpy installed.

Since you are converting to dB, it sounds like you might be taking a log. In that case, np.log(0) = -inf.

You can mask nans and infs with the numpy function np.ma.masked_invalid, and matplotlib can plot masked arrays. For example,

import matplotlib.pyplot as plt
import numpy as np

xvals=np.arange(100)
yvals=np.cumsum(np.random.random(100))
yvals[-10:]=0
yvals=np.log(yvals)

print(yvals[-10:])
# [-Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf -Inf]

yvals=np.ma.masked_invalid(yvals)
plt.plot(xvals,yvals)
plt.show()

yields enter image description here

Notice that the graph ends with xval equal to 89, since the last 10 values of yval are masked.

You're needlessly limiting yourself by refusing to use a looping construct.

In your situation you want to stop iterating over data when a certain value is reached, that is exactly the purpose of forloops and breaks

yvals_ = []
for y in yvals:
    y_ = f(y)
    if y_ == -140:
        break
    else:
        yvals_.append(y_)

p1.plot(xvals[:len(yvals_)],yvals_)

It seems like you have data, and you don't want to plot the last point. So what about not plotting it?

pl.plot(xvals[:-1], map(f, yvals)[:-1])
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top