如何使用 matplotlib 填充动画形状?

问题描述

我想绘制两个任意多边形(使用 shapely 计算面积、交集,因为我不知道另一种方法),然后填充交集,并在动画期间相交和移动时填充形状。

搜索后我不知道如何实现这一点。

我已审核:

  • set_fill
  • matplotlib 艺术家文档参考
  • fill_between
  • 动画
  • add_patch

但是,我相信我在这里一定遗漏了一些基本的东西,或者它可能不支持在动画期间填充对象,因为我能找到的唯一填充对象示例是静态图。

示例代码(最小示例,具有两个匀称的形状)如下,并已在 python 3 中测试为正常运行。

import numpy as np
import matplotlib.pyplot as plt
import shapely.geometry as sg
from matplotlib.animation import FuncAnimation

fig,ax = plt.subplots()

xdata,ydata = [],[]
x2data,y2data = [],[]

ln,= plt.plot([],[])
ln2,[])

def init():
    ax.axis('equal')
    ax.set_xlim(-4,4)
    ax.set_ylim(-4,4)
    return ln,ln2,def update(frame):
    fig.text(0,'hello')
    circ1 = sg.Point(frame-2,0).buffer(1.0)
    circ2 = sg.Point(-frame+2,0).buffer(1.0)

    x,y = circ1.exterior.xy
    x2,y2 = circ2.exterior.xy
    
    intersection = circ1.intersection(circ2)
    
    xdata.append(x)
    ydata.append(y)
     
    x2data.append(x2)
    y2data.append(y2)

    ln.set_data(x,y)
    ln2.set_data(x2,y2)
    
    return ln,ani = FuncAnimation(fig,update,frames=np.linspace(0,2,200),init_func=init,blit=True,interval = 10)
plt.show()

解决方法

由于您使用的是多边形,我建议您使用 matplotlib's Polygon 而不是线条来绘制形状。这允许您获取相交形状的坐标,并使用您选择的任何颜色绘制相应的多边形:

import numpy as np
import matplotlib.pyplot as plt
import shapely.geometry as sg
from matplotlib.animation import FuncAnimation
from matplotlib.patches import Polygon

fig,ax = plt.subplots()

poly1 = Polygon(np.zeros(shape=(0,2)),facecolor='none',edgecolor='C0')
poly2 = Polygon(np.zeros(shape=(0,edgecolor='C1')
intersect = Polygon(np.zeros(shape=(0,facecolor='C2',edgecolor='none')

ax.add_artist(poly1)
ax.add_artist(poly2)
ax.add_artist(intersect)
t = ax.text(0.5,0.9,"frame = ",transform=ax.transAxes,ha='center')


def init():
    ax.axis('equal')
    ax.set_xlim(-4,4)
    ax.set_ylim(-4,4)
    return poly1,poly2,t


def update(frame):
    t.set_text(f'frame = {frame:.3f}')
    circ1 = sg.Point(frame - 2,0).buffer(1.0)
    circ2 = sg.Point(-frame + 2,0).buffer(1.0)

    x,y = circ1.exterior.xy
    x2,y2 = circ2.exterior.xy

    intersection = circ1.intersection(circ2)

    poly1.set_xy(np.c_[x,y])
    poly2.set_xy(np.c_[x2,y2])

    if len(intersection.exterior.coords)>0:
        x3,y3 = intersection.exterior.coords.xy
        intersect.set_xy(np.c_[x3,y3])
        intersect.set_visible(True)
    else:
        intersect.set_visible(False)

    return poly1,intersect,t


ani = FuncAnimation(fig,update,frames=np.linspace(0,2,200),init_func=init,blit=True,interval=10)
plt.show()

enter image description here