【问题标题】:Pycharm SciView truncate historyPycharm SciView 截断历史
【发布时间】:2021-06-15 21:02:51
【问题描述】:

我正在尝试创建一个可以实时可视化投资组合变化的程序。为此,我更新了我的数据并用它创建了一个新图。当我在 PyCharm 中运行以下代码时,SciView 在 30 次迭代后停止显示图。理想情况下,我希望它只显示最近的情节,但如果它只是截断历史以便我至少总是看到当前情节也可以。有没有办法做到这一点?我尝试了不同的方法来关闭数字(例如使用plt.close()),但没有达到预期的结果。

要重现的代码:

import matplotlib.pyplot as plt
import numpy as np
import random


class RealTimeVisualizer:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def update_data(self, x_value, y_value):
        """
        Appends values to the data arrays.
        """
        self.x.append(x_value)
        self.y.append(y_value)

    def create_plot(self):
        """
        Takes an x and a y (both 1D arrays and constructs a plot from it)
        :return: a pyplot figure object
        """
        fig = plt.figure()
        ax = fig.add_subplot(1, 1, 1)

        # Draw x and y lists
        ax.clear()
        ax.plot(self.x, self.y)

        # Format plot
        plt.xticks(rotation=90)
        plt.title('Portfolio')
        plt.ylabel('Value')
        plt.show()
        plt.close('all')


if __name__ == '__main__':
    portfolio_cash = 10000
    tick = 0
    real_time_visualizer = RealTimeVisualizer([tick], [portfolio_cash])
    for i in np.arange(50):
        tick += 1
        portfolio_cash += random.randint(-50, 50)
        real_time_visualizer.update_data(tick, portfolio_cash)
        real_time_visualizer.create_plot()

【问题讨论】:

    标签: python matplotlib plot pycharm


    【解决方案1】:

    除了每次都创建新的绘图和窗口之外,您还可以在每次迭代中更新当前的 Matplotlib 图形数据。然后,您需要在交互式 Matplotlib 环境中查看绘图。

    实时更新 Matplotlib 图

    您可以使用类似的代码来更新图中的数据:

    import matplotlib.pyplot as plt
    import random
    
    plt.ion()  # Set pyplot to interactive mode
    fig = plt.figure()  # Create a figure
    ax = fig.add_subplot(111)  # Add a subplot to the figure
    
    # Variables for our updating data
    x = []
    y = []
    
    for i in range(50):
        # Generate random data
        x.append(i)
        y.append(random.random())
    
        # Update the plot with the new x, y data
        ax.plot(x, y, 'ro-')
        fig.canvas.draw()
        fig.canvas.flush_events()
    

    使用 SciView 时允许交互式 Matplotlib 模式

    停用 SciView 或手动将后端设置为另一个交互式 GUI 以查看更新图。 这段代码自动选择正确的后端(与Matplotlib code 中的列表相同):

    import matplotlib.pyplot as plt
    
    candidates = ["macosx", "qt5agg", "gtk3agg", "tkagg", "wxagg"]
    for candidate in candidates:
        try:
            plt.switch_backend(candidate)
            print('Using backend: ' + candidate)
            break
        except (ImportError, ModuleNotFoundError):
            pass
    

    应用于您的代码

    建议修改后的代码如下所示:

    import matplotlib.pyplot as plt
    import numpy as np
    import random
    
    
    class RealTimeVisualizer:
        def __init__(self, x, y):
            self.x = x
            self.y = y
    
        def update_data(self, x_value, y_value):
            """
            Appends values to the data arrays.
            """
            self.x.append(x_value)
            self.y.append(y_value)
    
        def update_plot(self, fig, ax):
            import _tkinter
            try:
                ax.plot(self.x, self.y, 'ro-')
                fig.canvas.draw()
                fig.canvas.flush_events()
            # Capture an error in case the plotting window is being closed
            except _tkinter.TclError:
                pass
    
    
    if __name__ == '__main__':
        portfolio_cash = 10000
        tick = 0
        real_time_visualizer = RealTimeVisualizer([tick], [portfolio_cash])
    
        # Choose the right backend
        candidates = ["macosx", "qt5agg", "gtk3agg", "tkagg", "wxagg"]
        for candidate in candidates:
            try:
                plt.switch_backend(candidate)
                print('Using backend: ' + candidate)
                break
            except (ImportError, ModuleNotFoundError):
                pass
    
        # Create plot
        plt.ion()  # Set pyplot to interactive mode
        fig = plt.figure()  # Create a figure
        ax = fig.add_subplot(111)  # Add a subplot to the figure
    
        for i in np.arange(50):
            tick += 1
            portfolio_cash += random.randint(-50, 50)
            real_time_visualizer.update_data(tick, portfolio_cash)
            real_time_visualizer.update_plot(fig, ax)  # Update the plot the new data
    

    【讨论】:

      【解决方案2】:

      同样的问题。

      我发现的解决方法是将 matplotlib 后端更改为在 PyCharm 之外绘图。

      import matplotlib
      matplotlib.use('qt5Agg')
      matplotlib.pyplot.ioff()
      
      

      然后你必须显式打开一个新图并显示

      for i in range(100):
          plt.figure()
          ...
          ...
          plt.show()
      

      【讨论】:

        猜你喜欢
        • 2012-06-21
        • 1970-01-01
        • 2023-03-28
        • 1970-01-01
        • 2017-11-03
        • 2021-09-16
        • 2023-03-24
        • 2019-12-15
        相关资源
        最近更新 更多