matplotlib 中带有散点图和使用 set_offsets 的动画:图形的自动缩放不起作用

Posted

技术标签:

【中文标题】matplotlib 中带有散点图和使用 set_offsets 的动画:图形的自动缩放不起作用【英文标题】:Animation in matplotlib with scatter and using set_offsets: Autoscale of figure is not working 【发布时间】:2017-04-28 07:51:40 【问题描述】:

我正在使用 matplotlib 在 python GUI 中使用动画进行绘图。下面是代码

import sys
from PyQt4 import QtGui

from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt4agg import NavigationToolbar2QT as NavigationToolbar
import matplotlib.pyplot as plt
import matplotlib.animation
import numpy as np
class Window(QtGui.QDialog):
    def __init__(self, parent=None):
    super(Window, self).__init__(parent)
    self.figure = plt.figure()
    self.canvas = FigureCanvas(self.figure)
    self.toolbar = NavigationToolbar(self.canvas, self)
    layout = QtGui.QVBoxLayout()
    layout.addWidget(self.toolbar)
    layout.addWidget(self.canvas)
    self.setLayout(layout)
    self.ax=self.figure.add_subplot(111)

    plt.autoscale(enable=True, axis='both', tight=None #for auto scaling

    self.data = [500, -500, 501, -502,.... 623] #some list of data
    self.ax = plt.gca()
    self.ax.grid()
    self.sc = self.ax.scatter(self.data[::2], self.data[1::2]

def plot(self, a):
    for i in range(len(self.data)):
        self.data[i] = int(self.data[i])+5
    self.sc.set_offsets(np.c_[self.data[::2], self.data[1::2]])
    self.canvas.draw()

if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)

    main = Window()
    ani = matplotlib.animation.FuncAnimation(main.figure, main.plot, 
            frames=4, interval=100, repeat=True) 
    main.show()

    sys.exit(app.exec_())

我正在使用动画调用的绘图函数中的 set_offsets 更新绘图。当绘图值不断增加并且绘图完成时,绘图会变得不正常。所以我使用了自动缩放()。但它不工作。静止轴保持固定,绘图消失。 请帮助我在图中进行自动缩放。提前致谢。

【问题讨论】:

我相信它现在看起来不错.. @ImportanceOfBeingErnest 【参考方案1】:

问题是在自动缩放轴时没有考虑散射偏移。这可能是一个错误,或者是一个期望的特性;无论如何,两种解决方法是:

使用plot

在许多情况下可以接受的一种解决方法是使用线图plt.plot 而不是plt.scatter。在这种情况下,可以使用ax.relim 后跟ax.autoscale_view() 自动缩放轴。

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

fig, ax = plt.subplots()  
ax.grid()  

data = np.cumsum(np.random.normal(size=100)) #some list of data
sc, = ax.plot(data[::2], data[1::2], marker="o", ls="") # set linestyle to none

def plot(a, data):
    data += np.cumsum(np.random.normal(size=100)+3e-2)
    sc.set_data(data[::2], data[1::2])
    ax.relim()
    ax.autoscale_view(True,True,True)

ani = matplotlib.animation.FuncAnimation(fig, plot, fargs=(data,),
            frames=4, interval=100, repeat=True) 
plt.show()

使用scatter 并以编程方式设置限制

如果不能使用上述方法(例如,因为散点应该具有不同的大小或颜色),则需要根据数据更新限制。

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

fig, ax = plt.subplots()    

data = np.cumsum(np.random.normal(size=100)) #some list of data

ax.grid()
sc = ax.scatter(data[::2], data[1::2], c=data[1::2])

def plot(a, data):
    data += np.cumsum(np.random.normal(size=100)+3e-2)
    X = np.c_[data[::2], data[1::2]]
    sc.set_offsets(X)
    # manually relim:
    xmin=X[:,0].min(); xmax=X[:,0].max()
    ymin=X[:,1].min(); ymax=X[:,1].max()
    ax.set_xlim(xmin-0.1*(xmax-xmin),xmax+0.1*(xmax-xmin))
    ax.set_ylim(ymin-0.1*(ymax-ymin),ymax+0.1*(ymax-ymin))

ani = matplotlib.animation.FuncAnimation(fig, plot, fargs=(data,),
            frames=4, interval=100, repeat=True) 
plt.show()

【讨论】:

当我尝试这种方法时,我得到了一个回溯'AttributeError:'PathCollection'对象没有属性'set_xlim''。请问有什么想法吗? 没有。首先,上面有两种方法。不清楚你拿的是哪一个。其次,两者都按原样工作。如果你改变了什么,别人怎么会知道你改变了什么。因此,没有人可以帮助您,除非您提供问题的minimal reproducible example。最好通过提出一个新问题来做到这一点。 感谢您的回复。我用的是第二种方法。我在 PathCollection 而不是轴对象上错误地调用了 set_xlim。它现在正在工作。 感谢发帖。 是否可以添加更新趋势线以及散点?

以上是关于matplotlib 中带有散点图和使用 set_offsets 的动画:图形的自动缩放不起作用的主要内容,如果未能解决你的问题,请参考以下文章

matplotlib 散点图和注释函数annotate

matplotlib-直方图、箱体图、散点图

Matplotlib 绘制直方图、散点图

转录组scatter plot 散点图和ma plot有啥区别

matplotlib:通过用于为散点图着色的对数颜色条值对 2D 线进行着色

Python使用matplotlib模块绘制多条折线图散点图