【问题标题】:Can matplotlib and readchar work simultaneously?matplotlib 和 readchar 可以同时工作吗?
【发布时间】:2019-08-30 03:52:33
【问题描述】:

我正在尝试使用 w、a、s 和 d 键在 matplotlib 图周围移动一个点,而无需在每次键入字母后按 Enter。这使用 readchar.readchar() 有效,但随后情节不显示。我做错了什么?

""" Moving dot """
import matplotlib.pyplot as plt
import time
import readchar

x = 0
y = 0
q = 0
e = 0
counter = 0
while 1 :
    #arrow_key = input()
    arrow_key = readchar.readchar()
    print(x,y)
    if arrow_key == "d" :
        q = x + 1
    elif arrow_key == "a" :
        q = x - 1
    elif arrow_key == "w" :
        e = y + 1
    elif arrow_key == "s" :
        e = y - 1
    plt.ion()   
    plt.plot(x,y, "wo", markersize = 10)
    plt.plot(q,e, "bo")
    plt.xlim(-10,10)
    plt.ylim(-10,10)
    x = q
    y = e

【问题讨论】:

    标签: python matplotlib


    【解决方案1】:

    代码中的第一个问题是 readchar.readchar() 返回二进制字符串。您需要将其解码为 utf-8:arrow_key = readchar.readchar().lower().decode("utf-8")

    我认为最好在 while 循环之前执行 plt.xlim()plt.ylim() 限制。

    如果我不使用plt.pause(),我的plt 会冻结。我添加了多个plt.pause(0.0001) 以使代码正常工作。参考:Matplotlib ion() function fails to be interactive

    此外,在显示绘图之前,您需要用户在代码中输入。我将其更改为在用户输入之前显示的绘图。

    最好在输入之前将x 更改为q 并将y 更改为e。它是在输入之后导致之前的图显示给我的。

    编辑: 正如 FriendFX 下面建议的那样,最好将图定义为变量(pl1 = plt.plot(x,y, "wo", markersize = 10)pl2 = plt.plot(q,e, "bo"))并在使用后将其删除,以免填满内存。 pl1.pop(0).remove()pl2.pop(0).remove()

    下面的完整修复代码。请注意,在启动时您可能会失去终端窗口焦点,这对输入至关重要。

    import matplotlib.pyplot as plt
    import time # you didn't use this, do you need it?
    import readchar
    
    x = 0
    y = 0
    q = 0
    e = 0
    plt.xlim(-10,10)
    plt.ylim(-10,10)
    
    counter = 0 # you didn't use this, do you need it?
    while(1):
        plt.ion()
        plt.pause(0.0001)
        pl1 = plt.plot(x,y, "wo", markersize = 10)
        pl2 = plt.plot(q,e, "bo")
        plt.pause(0.0001)
        plt.draw()
        plt.pause(0.0001)
        x = q
        y = e
    
        arrow_key = readchar.readchar().lower().decode("utf-8")
        print(arrow_key)
    
        if arrow_key == "d" :
            q = x + 1
        elif arrow_key == "a" :
            q = x - 1
        elif arrow_key == "w" :
            e = y + 1
        elif arrow_key == 's' :
            e = y - 1
        print(q, e, x, y)
        pl1.pop(0).remove()
        pl2.pop(0).remove()
    

    【讨论】:

    • 不错的一个。根据 OP 的需要,使用lines.pop(0).remove() 删除现有绘图点也可能会有所帮助,如this answer 中所述,其中lines 是一个变量,用于存储plt.plot() 调用中的一个(或两者)的输出,例如line = plot.plot(q,e, "bo")。另外,我认为循环中不需要show() 调用。
    • @FriendFX 你是对的。添加了您的建议并删除了plt.show()
    猜你喜欢
    • 2014-05-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-09
    • 2016-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多