我用matplotlib和Python遇到了一个相当严重的问题.我有一个密集的周期图数据集,想要绘制它.问题是,当像素上绘制的数据点多于可以绘制的数据点时,包不会选择要显示的最小值和最大值.这意味着随意看一下情节可能会导致错误的结论.
以下是此类问题的示例:

数据集用plot()和绘制并scatter()叠加.您可以看到,在密集数据字段中,连接数据的蓝线未达到实际峰值,导致人类观察者在最大值处达到最大值,而实际上并非如此.
如果放大或强制使用宽视图窗口,则会正确显示. rasterize和aa关键字对此问题没有影响.
有没有办法确保plot()始终呈现呼叫的最小/最大点?否则,需要在matplotlib的更新中解决这个问题.我从未有过这样的情节包,这是一个非常重要的问题.
编辑:
x = numpy.linspace(0,1,2000000)
y = numpy.random.random(x.shape)
y[1000000]=2
plot(x,y)
show()
Run Code Online (Sandbox Code Playgroud)
应该复制问题.虽然它可能取决于您的显示器分辨率.通过拖动窗口并调整其大小,您应该会看到问题所在.一个数据点应该突出ay = 2,但并不总是显示.
这是由于matplotlib中的路径简化算法.虽然在某些情况下它肯定是不可取的,但它是加速渲染的故意行为.
简化算法在某些时候被改变以避免跳过"异常"点,因此mpl的较新版本不会表现出这种确切的行为(尽管路径仍然是简化的).
如果您不想简化路径,则可以在rc参数中(在.matplotlibrc文件中或在运行时)禁用它.
例如
import matplotlib as mpl
mpl.rcParams['path.simplify'] = False
import matplotlib.pyplot as plt
Run Code Online (Sandbox Code Playgroud)
但是,使用"信封"风格的情节可能更有意义.作为一个简单的例子:
import matplotlib.pyplot as plt
import numpy as np
def main():
num = 10000
x = np.linspace(0, 10, num)
y = np.cos(x) + 5 * np.random.random(num)
fig, (ax1, ax2) = plt.subplots(nrows=2)
ax1.plot(x, y)
envelope_plot(x, y, winsize=40, ax=ax2)
plt.show()
def envelope_plot(x, y, winsize, ax=None, fill='gray', color='blue'):
if ax is None:
ax = plt.gca()
# Coarsely chunk the data, discarding the last window if it's not evenly
# divisible. (Fast and memory-efficient)
numwin = x.size // winsize
ywin = y[:winsize * numwin].reshape(-1, winsize)
xwin = x[:winsize * numwin].reshape(-1, winsize)
# Find the min, max, and mean within each window
ymin = ywin.min(axis=1)
ymax = ywin.max(axis=1)
ymean = ywin.mean(axis=1)
xmean = xwin.mean(axis=1)
fill_artist = ax.fill_between(xmean, ymin, ymax, color=fill,
edgecolor='none', alpha=0.5)
line, = ax.plot(xmean, ymean, color=color, linestyle='-')
return fill_artist, line
if __name__ == '__main__':
main()
Run Code Online (Sandbox Code Playgroud)

| 归档时间: |
|
| 查看次数: |
1578 次 |
| 最近记录: |