简体   繁体   English

你如何实时 plot 颜色图?

[英]How do you real-time plot a colormap?

I am currently working on creating a Qt window with 3 matplotlib colormaps.我目前正在创建一个 Qt window 和 3 matplotlib 颜色图。

The process is something like this:这个过程是这样的:

  1. The user will input the x and y values of the plots into a GUI (each plot will have the same x and y values).用户将绘图的 x 和 y 值输入到 GUI 中(每个 plot 将具有相同的 x 和 y 值)。
  2. These values will be converted and then sent to a microprocessor which will communicate with both a DAC and ADC (Instrument "stuff" happens on the "backend" between the DAC and ADC, ie a spectrum analyzer takes noise measurements).这些值将被转换,然后发送到微处理器,微处理器将与 DAC 和 ADC 通信(仪器“东西”发生在 DAC 和 ADC 之间的“后端”,即频谱分析仪进行噪声测量)。
  3. For each x and y point, we will receive one z value for each colormap.对于每个 x 和 y 点,我们将收到每个颜色图的一个 z 值。 To emphasize: This means that each subplot will need to update simultaneously.强调一下:这意味着每个子图都需要同时更新。

I am currently working on the script that will real-time graph these colormaps in a Qt window as the data is being taken.我目前正在编写脚本,该脚本将在获取数据时在 Qt window 中实时绘制这些颜色图。 I can find readily accessible resources on how to real-time plot line graphs;我可以找到有关如何实时 plot 折线图的现成资源; however, I am unable to find anything for colormaps.但是,我找不到任何颜色图。 Here is the code I have so far:这是我到目前为止的代码:

import sys
import time
import random

import numpy as np

from matplotlib.backends.qt_compat import QtWidgets
from matplotlib.backends.backend_qt5agg import (
    FigureCanvas, NavigationToolbar2QT as NavigationToolbar)
from matplotlib.figure import Figure
from matplotlib.colors import ListedColormap, LinearSegmentedColormap
import matplotlib as mpl
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import make_axes_locatable


# Quick note, this will need to be a widget class in the final version so it can be run from the kalamari main window
# but I think that will just change how the class is initalized

class ApplicationWindow(QtWidgets.QMainWindow):
    def __init__(self):
        # set up the window
        super().__init__()
        self._main = QtWidgets.QWidget()
        self.setCentralWidget(self._main)
        # It seems as though this layout is what is going to allow me to
        # orient all 3 subplots onto the same y axis
        layout = QtWidgets.QVBoxLayout(self._main)

        # create seperate canvas objects
        first_canvas = FigureCanvas(Figure(figsize=(9, 6)))
        layout.addWidget(NavigationToolbar(first_canvas, self))
        layout.addWidget(first_canvas)

        second_canvas = FigureCanvas(Figure(figsize=(9, 3)))
        layout.addWidget(second_canvas)
        layout.addWidget(NavigationToolbar(second_canvas, self))

        # add subplots to the first canvas
        self._first_axs = first_canvas.figure.subplots(1, 3)

        # create data and colormap

        # Here I replace X and Y with coordinate vectors which are just np.linspace
        x = np.linspace(0, 10, 10)
        y = np.linspace(0, 10, 10)
        # For the final version you can use x for flux and y for biases and then have
        # each row of z be the voltages, such that:
        # z[i,j] is V(bias[j], flux[i])
        # Then here is the data I will use to determine the color,
        # this needs to have the same dimension as the coordinates
        z = np.random.rand(10, 10)

        custom_cmap = mpl.colors.LinearSegmentedColormap.from_list(
            "custom", ["#00008B", "blue", "cyan", "green", "yellow", "orange", "red", "#8B0000"])

        # access each subplot using regular indexing
        self._first_axs[0].set_title(
            'I' + u'\u209B' + u'\u2092' + u'\u209C', size=40)
        self._first_axs[1].set_title(
            'dI' + u'\u209B' + u'\u2092' + u'\u209C' + '/dt', size=40)
        self._first_axs[2].set_title('Noise', size=40)

        # plot data and create colorbars
        self.plot1 = self._first_axs[0].contourf(
            x, y, z, levels=20, cmap=custom_cmap)
        self.plot2 = self._first_axs[1].contourf(
            x, y, z, levels=20, cmap=custom_cmap)
        self.plot3 = self._first_axs[2].contourf(
            x, y, z, levels=20, cmap=custom_cmap)
        self.cbar1 = first_canvas.figure.colorbar(
            self.plot1, ax=self._first_axs[0], orientation='horizontal')
        self.cbar2 = first_canvas.figure.colorbar(
            self.plot2, ax=self._first_axs[1], orientation='horizontal')
        self.cbar3 = first_canvas.figure.colorbar(
            self.plot3, ax=self._first_axs[2], orientation='horizontal')

        # make the second canvas a dynamic plot
        self._second_ax = second_canvas.figure.subplots()
        t = list(range(50))
        self.yData = [random.randint(0, 10) for i in range(50)]

        # Set up a Line2D.
        self._line, = self._second_ax.plot(t, self.yData)
        self._timer = second_canvas.new_timer(50)
        self._timer.add_callback(self._update_canvas)
        self._timer.start()

    def _update_canvas(self):
        t = list(range(50))
        self.yData = self.yData[1:] + [random.randint(0, 10)]
        # set line data
        self._line.set_data(t, self.yData)
        self._line.figure.canvas.draw()


if __name__ == "__main__":
    # Check for open QApplication.instance()
    qapp = QtWidgets.QApplication.instance()
    if not qapp:
        qapp = QtWidgets.QApplication(sys.argv)

    # run it!
    app = ApplicationWindow()
    app.show()
    app.activateWindow()
    app.raise_()
    qapp.exec()

This code currently produces 1 Qt window with 2 separate "canvases".此代码当前生成 1 Qt window 和 2 个单独的“画布”。 The first canvas is the 3 colormaps, the second is a line plot that real-time graphs.第一个 canvas 是 3 个颜色图,第二个是实时图形的线 plot。

Top Plots热门地块

  • These are static, but I would like them to be dynamic.这些是 static,但我希望它们是动态的。
  • Would anybody be able to help me determine how to real-time plot these colormaps as I am collecting data?有人能帮我确定如何在我收集数据时实时 plot 这些颜色图吗?

在此处输入图像描述

Bottom Plot底部 Plot

  • This runs in real-time这是实时运行的
  • I do not need the line graph for my purposes.对于我的目的,我不需要折线图。 It is just there as a reference to real-time plotting methods.它只是作为实时绘图方法的参考。

在此处输入图像描述

You can try replotting the contour with every update call.您可以尝试在每次更新调用时重新绘制轮廓。 I use ax.cla() to clear the current plot, before plotting new information.在绘制新信息之前,我使用ax.cla()清除当前的 plot。 This script is an example of what that might look like.这个脚本是一个可能看起来像的例子。

import numpy as np
import matplotlib.pyplot as plt

rng = np.random.default_rng()

N = 25
x = np.linspace(-1, 1, N)
y = np.linspace(-1, 1, N)

Niter = 25
fig, ax = plt.subplots()
ax.set_aspect(1)
for _ in range(Niter):
    ax.cla()
    z = rng.uniform(size=(N,N))
    ax.contourf(x, y, z)
    fig.canvas.draw()
    renderer = fig.canvas.renderer
    ax.draw(renderer)
    plt.pause(0.01)

在此处输入图像描述

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

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