pyplot 图仅在第二次调用 ginput() 后更新

pyplot figure only updating after second call to ginput()

我有一个方法使用 matplotlib.pyplot.ginput() 从坐标轴收集单击的位置,然后将图像放置在同一图中现有底层坐标轴阵列中的该位置。

视觉仅在第二次调用 ginput() 后更新,这意味着它的响应与用户的点击相比是滞后的,并且只有当他们选择下一个位置时,他们刚刚放置的图像才会显示。这是有问题的,因为放置的随机图像可能会影响他们接下来要点击的位置。

调用方法类似于下面的内容,尽管这里绘制的是坐标轴而不是添加的图像:

%matplotlib
from matplotlib import pyplot
import numpy
import random

dimensions = [10,10]

visual_width = 1366
visual_height = 768
print("Established screen dimensions as "+str(visual_width)+","+str(visual_height))
         
fig, axarr = pyplot.subplots(dimensions[1],dimensions[0]
                               , num="Live game visualised"
                            , figsize=(visual_width, visual_height)
                            , clear=True)
fig.set_size_inches(visual_width, visual_height, forward=False)
overax = fig.add_subplot(111)
overax.axis("off")
#remove axes for initial rendering
for horizontal in range(0, dimensions[0]):
    for vertical in range(0, dimensions[1]):
        axarr[vertical, horizontal].axis('off')
text = fig.text(0,0, "", va="bottom", ha="left")

# test repeated interactions with figure, through successively adding tiles to the play area
playing = True
while playing:
    click = pyplot.ginput()
    if not click:
        break
    
    horizontal = int(click[0][0]*dimensions[0])
    vertical = dimensions[1] - int(click[0][1]*dimensions[1])
    print(str(horizontal)+","+str(vertical))
    text.set_text(str(horizontal)+","+str(vertical))
    axarr[vertical-1, horizontal].axis("on")

我的 python 3 脚本在 jupyter notebook 中,但我使用默认的 %matplotlib 后端弹出视觉效果。我在 Chrome Ubuntu 工作。

这是一个棘手且不令人满意的解决方案,但我的解决方法是提示双击,并接受对 ginput 的第一次调用是将存储到分配给第二次调用的变量的数据:

%matplotlib
from matplotlib import pyplot
import numpy
import random

dimensions = [10,10]

visual_width = 1366
visual_height = 768
print("Established screen dimensions as "+str(visual_width)+","+str(visual_height))
         
fig, axarr = pyplot.subplots(dimensions[1],dimensions[0]
                               , num="Live game visualised"
                            , figsize=(visual_width, visual_height)
                            , clear=True)
fig.set_size_inches(visual_width, visual_height, forward=False)
overax = fig.add_subplot(111)
overax.axis("off")
#remove axes for initial rendering
for horizontal in range(0, dimensions[0]):
    for vertical in range(0, dimensions[1]):
        axarr[vertical, horizontal].axis('off')
text = fig.text(0,0, "", va="bottom", ha="left")

# test repeated interactions with figure, through successively adding tiles to the play area
playing = True
while playing:
    pyplot.ginput()
    click = pyplot.ginput()
    if not click:
        break
    
    horizontal = int(click[0][0]*dimensions[0])
    vertical = dimensions[1] - int(click[0][1]*dimensions[1])
    print(str(horizontal)+","+str(vertical))
    text.set_text(str(horizontal)+","+str(vertical))
    axarr[vertical-1, horizontal].axis("on")
    
    text.set_text("Double click to make your next move")   

我觉得我的问题和你的类似。我正在使用自己的方法放大 ginput 选择的图像区域。

这是我使用 plt.ionplt.draw 的解决方案,在我的脚本中运行良好。 image super resolution 方法被删除。

#!/usr/bin/env python
import matplotlib.pyplot as plt
import numpy as np

import argparse
import sys

parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument(
    "-i", "--image_name", type=str, default="test.jpg", help="Input image path"
)
args = parser.parse_known_args(sys.argv[1:])[0]

plt.ion()  # works in `.py` scripts
imm = plt.imread(args.image_name)
fig = plt.figure()
plt.imshow(imm)
plt.tight_layout()
plt.show()

imms = [imm]
while True:
    aa = plt.ginput(2, timeout=-1)
    aa = np.array(aa)

    left, right = int(aa[:, 0].min()), int(aa[:, 0].max())
    top, bottom = int(aa[:, 1].min()), int(aa[:, 1].max())

    if right - left < 1 or bottom - top < 1:  # Double click to return
        if len(imms) > 1:
            imms.pop(-1)
        else:
            break
    else:
        sub_image = imms[-1][top:bottom, left:right, :]
        imms.append(sub_image)
    plt.imshow(imms[-1])
    plt.draw()  # works in `ipython` environment

在我的测试中:

  • 添加 plt.ion 而没有最后一个 plt.draw.py 脚本中仍然有效。
  • ipython 环境中添加没有 plt.ion 的最后一个 plt.draw