繁体   English   中英

Plot 移动值范围 window 与 matplotlib

[英]Plot range of values in moving window with matplotlib

我想移动 window,当它在数据中移动时,将 plot 每个框中的值范围。 我一直在像这样运行 window:

import numpy as np
from astropy.convolution import convolve

x = np.random.randint(10,size=(10,10))
y = convolve(x,np.ones((5,5)),boundary='extend',preserve_nan=True)

print('x:',x)
print('y:',y)

 x: [[0 2 7 7 3 8 0 5 5 7]
 [6 8 0 6 2 0 0 0 9 7]
 [7 4 4 1 5 1 1 6 1 8]
 [8 9 5 2 3 5 4 2 6 5]
 [0 7 2 4 3 6 6 6 7 5]
 [0 0 8 3 2 8 1 0 7 9]
 [5 2 0 6 3 3 0 0 6 0]
 [1 0 2 9 7 9 7 6 5 6]
 [5 6 5 5 5 3 8 0 6 4]
 [5 9 9 5 2 8 1 3 0 6]]

y: [[6.12 6.08 6.2  5.64 5.68 4.72 3.88 3.04 2.88 2.24]
 [5.68 5.68 5.76 5.28 5.6  4.76 4.   3.4  3.36 2.8 ]
 [5.44 5.24 5.32 4.96 5.16 4.76 4.08 3.44 3.24 2.88]
 [5.32 4.96 4.92 4.4  4.6  4.2  3.64 3.08 3.   2.68]
 [4.96 4.8  4.92 4.68 4.72 4.4  3.8  3.4  3.36 3.44]
 [4.52 4.44 4.52 4.4  4.48 4.24 3.76 3.4  3.24 3.24]
 [4.12 4.2  4.36 4.12 3.76 3.8  3.44 3.2  3.36 3.68]
 [3.32 3.84 4.24 3.92 3.8  3.76 3.44 3.48 4.24 4.72]
 [2.4  3.32 4.08 3.96 3.96 4.28 3.96 4.16 5.24 6.04]
 [2.08 3.16 4.32 4.16 4.36 4.6  4.4  4.44 5.8  6.64]]

这会计算每个 5x5 window 的平均值,但是有没有办法显示x中的值范围? 所以说 window 来自x的左上角:

0 2 7 7 3 
6 8 0 6 2 
7 4 4 1 5 
8 9 5 2 3 
0 7 2 4 3

范围是从 0 到 9,所以在 matplotlib plot 上,将绘制一个 9,并且对于在数据中移动的每个 window 都会重复。 所以最终的 plot 看起来像:

在此处输入图像描述

使用mplcursors可以交互地标记一个区域并通过注释显示值。

import matplotlib.pyplot as plt
from matplotlib.patches import Rectangle
import mplcursors
import numpy as np
from astropy.convolution import convolve

def show_rect(sel):
    i, j = sel.target.index
    i0 = 0 if i - 2 < 0 else i - 2
    i1 = x.shape[0] - 1 if i + 2 >= x.shape[0] else i + 2
    j0 = 0 if j - 2 < 0 else j - 2
    j1 = x.shape[1] - 1 if j + 2 >= x.shape[1] else j + 2
    annotation_text = f'{i},{j}: {x[sel.target.index]}\n5x5 average: {y[sel.target.index]:.2f}'
    sel.annotation.set_text(annotation_text)
    sel.annotation.get_bbox_patch().set(fc='gold', alpha=0.7)
    rect = Rectangle((j0 - 0.5, i0 - 0.5), j1 - j0 + 1, i1 - i0 + 1,
                     linewidth=3, color='lime', alpha=0.3, clip_on=False)
    ax.add_artist(rect)
    sel.extras.append(rect)

x = np.random.randint(10, size=(10, 15))
y = convolve(x, np.ones((5, 5)), boundary='extend', preserve_nan=True)

fig, ax = plt.subplots(figsize=(9, 3))
img = ax.imshow(x, cmap='coolwarm', aspect='auto', alpha=0.8)
ax.set_xticks(range(x.shape[1]))
ax.set_yticks(range(x.shape[0]))
fig.colorbar(img, ticks=range(10), ax=ax)
for i in range(x.shape[0]):
    for j in range(x.shape[1]):
        ax.text(j, i, x[i, j], ha='center', va='center')
cursor = mplcursors.cursor(img, hover=True)
cursor.connect('add', show_rect)
plt.show()

示例图

要创建xy的线性 plot,您可以使用np.ravel()将它们转换为一维:

import matplotlib.pyplot as plt
import numpy as np
from astropy.convolution import convolve

x = np.random.randint(10, size=(10, 10))
y = convolve(x, np.ones((5, 5)), boundary='extend', preserve_nan=True)

fig, ax = plt.subplots(figsize=(9, 3))

ax.plot(np.arange(x.size), x.ravel(), color='dodgerblue', label='input values')
ax.plot(np.arange(x.size), y.ravel(), color='crimson', label='convolution')

ax.set_xticks(np.arange(x.size))
ax.set_xticklabels([f'[{i},{j}]' for i in range(x.shape[0]) for j in range(x.shape[1])], rotation=90, size=8)
ax.margins(x=0.02)
ax.legend(bbox_to_anchor=[1.02, 1.02], loc='upper left')
plt.tight_layout()
plt.show()

第二个情节

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM