python - 将 Matplotlib 绘图绘制到 Psychopy 循环中

标签 python matplotlib psychopy

我使用 Psychopy 和 Matplotlib 在屏幕左侧显示 100 个随机方向 (0,360)、大小和位置的矩形。我正在为方向的每个象限分配一个独特的颜色(即所有方向 < 90 的红色,ori >90 和 < 180 的绿色,所有 >180 和 <270 的蓝色,所有 > 270 的灰色)。我一直在计算每个矩形中有多少落在这些范围内,然后使用 Matplotlib 绘制它们。我通过保存图表在屏幕右侧显示该图表,然后使用 Psychopy Imagestim 将其调回。我将这个脚本保存在一个函数中,然后运行该函数 n 次。这个想法是,在每次按键时,我都会得到一个新的矩形显示(左侧)和一个新的伴随图形(右侧)。

我的问题是,虽然矩形和矩形计数显示正常,但图表没有正确更新。例如,如果在第一次试验中有 24 个红色,则红色条将显示这一点。但是,如果在下一次试验中有 22 个红色,则图形的红色部分不会减少到 23,它会保持在 24。基本上只会增加。整个图表(所有颜色)都是这种情况,导致图表在每次试验中只增加每个条(没有减少)。我不明白为什么会这样。我认为我将 4 个(颜色)变量传递给 Matplotlib 的方式存在问题,但在每次试验开始时它们都被重置为 0;出于这个原因,我无法找出问题所在。

import random
import psychopy.visual
import psychopy.event
import psychopy.core
import numpy as np
import matplotlib.pyplot as plt

win = psychopy.visual.Window(
    size = [1200,550],
    units = "pix",
    fullscr=False,
    color=[-1,-1,-1]
)

def one():
    win.flip()
    rect=psychopy.visual.Rect(win=win,units="pix") 

    n_rect=100

    performance = []

    red   = 0
    green = 0
    blue  = 0
    grey  = 0

    for i_rect in range(n_rect):                               
        rect.width = random.uniform(10,100)
        rect.height = random.uniform(10,100)
        rect.ori = random.uniform(0,360)

        rect.pos = [
            random.uniform(-300,-10),
            random.uniform(-300,300)
        ]

        if rect.ori < 90:
            rect.fillColor = (1,-1,-1)
            red += 1

        elif rect.ori >90 and rect.ori <180:
            rect.fillColor = (-1,1,-1)
            green += 1

        elif rect.ori > 180 and rect.ori < 270:
            rect.fillColor = (-1,-1,1)
            blue += 1

        else:
            rect.fillColor = (0,0,0)
            grey += 1

        rect.draw()

    print ("red:   %i")%(red)
    print ("green: %i")%(green)
    print ("blue:  %i")%(blue)
    print ("grey:  %i")%(grey)

    red_text   =  psychopy.visual.TextStim(win,text =  red,  pos =  (165,-180))
    green_text =  psychopy.visual.TextStim(win,text =  green,pos = (295,-180))
    blue_text  =  psychopy.visual.TextStim(win,text =  blue, pos = (425,-180))
    grey_text  =  psychopy.visual.TextStim(win,text =  grey, pos = (555,-180)) 

    color_text_list = [red_text,green_text,blue_text,grey_text]

    for color in color_text_list:
        color.draw()

    # Here I pass the value of my colour variables to Matplotlib for plotting

    plt.style.use('ggplot')
    colors = ('red','green','blue','grey')
    y_pos = np.arange(len(colors))
    performance = [red,green,blue,grey]

    x = plt.bar(y_pos, performance, align='center')
    x[0].set_color('red')
    x[1].set_color('green')
    x[2].set_color('blue')
    x[3].set_color('grey')
    plt.xticks(y_pos, colors)
    plt.ylabel('count')

    plt.savefig('image.png',dpi=80,transparent=True)

    img = psychopy.visual.ImageStim(
        win=win,
        image="image.png",
        units="pix",
        pos = (350,50)
    )

    rect.draw()
    img.draw()
    win.flip()

    psychopy.event.waitKeys()

for i in range(20):
    one()

win.close()

如果有人想尝试,代码可以自己运行。代码相对简单,但这是我第一次使用 Matplotlib,可能我遗漏了一些明显的东西。

谢谢, 史蒂夫

最佳答案

我无法验证,因为我目前没有安装 psychopy,但我认为你的问题是你没有在每次迭代后清除你的 pyplot 图.

def one():
    ...
    ...
    performance = [red,green,blue,grey]
    #Clears the current plot figure, leaves the window open.
    plt.clf()
    x = plt.bar(y_pos, performance, align='center')
    ...
    ...

pyplot 跟踪当前事件的图形,并将继续绘制到该图形(不清除以前的数据),直到您另有指示。您也可以调用 plt.figure() 打开一个新图,但请确保关闭前一个图以清理内存。

有关清除地 block 的不同方法的更详细说明,请参阅此问题 - When to use cla(), clf() or close() for clearing a plot in matplotlib?

关于python - 将 Matplotlib 绘图绘制到 Psychopy 循环中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41214053/

相关文章:

python - 按下回车键后如何让字符串出现

python - python初始化时如何访问父类?

python - Django `extends` 是否接受命名空间解析的模板?

python - tripcolor 使用每个顶点的 RGB 值

python - 在 python 中使用 matplotlib 创建 3D 曲面图

python - 使用 matplotlib pyplot 绘制实时饼图

psychopy - 了解 TrialHandler 和响应的 PsychoPy 代码

python-3.x - python中Eye-Tracking数据分析(Eye-link)

python - Scrapy 选择具有特定属性名称的 HTML 元素

Psychopy ISI 组件以及如何使用它在 Builder 中加载刺激