首页 > 解决方案 > 幻灯片更新后的 Matplotlib fill_between 不会重绘

问题描述

我正在画一条简单的线(y = mx + b),我正在围绕原点旋转它(仅在第一象限中),我正在填充线和 x 轴之间。我通过滑块更改线的斜率。我已经对此进行了研究,看来为了在线条旋转时保持区域填充是使用“集合”,它已实现但现在我进入了一个无限循环。具体来说,当我更改滑块时,填充区域是正确的,但仅适用于滑块的一次更改。在此之后它进入一个无限循环。任何帮助,将不胜感激。我的代码的主要部分如下:

import matplotlib.pyplot as plt
import numpy as np
import matplotlib.animation
from matplotlib.widgets import Slider  # import the Slider widget

fig = plt.figure()

axcolor = 'lightgoldenrodyellow'
main_ax = plt.axes([0, .5, 10, 15])
slider_ax = plt.axes([0.2, 0.08, .7, .03], facecolor=axcolor)   

#Some constants
torad = np.pi/180
WAngle = 20.
xmax = 10

#Slider min max
s_min = 00
s_max = 60
s_init = WAngle

# set the current plot to main_ax
plt.sca(main_ax)

#Define and plot the triangle
plt.axes() #Select the main axis
plt.title('test')
plt.xlim(0,10)
plt.ylim(0,10)

#Now define the line, only need the second point, first point 0,0
Beta = WAngle
Bx = 10
By = Bx*np.tan(Beta * torad)

# Draw line and add to plot
xdat = [0, 10]
ydat = [0, By]
line = plt.Line2D(xdat, ydat,color='k')  #(x1,x2),(y1,y2)   
axis = plt.gca()
axis.add_line(line) 
fillbet = plt.fill_between(xdat, ydat, color="#539ecd",label="wedge")
sline = Slider(slider_ax, 'line', s_min, s_max, valinit=s_init) 

## def update(val): 
def update(val):
    myangle = sline.val
    By = Bx*np.tan(myangle * torad)
    xdat = [0, Bx]
    ydat = [0, By]
    line.set_xdata((0, Bx))
    line.set_ydata((0, By))
    for collection in axis.collections:
        if str(collection.get_label()) == "wedge":
            collection.remove()
            del collection
        fillbet = plt.fill_between(xdat, ydat, color='#539ecd')
    plt.gcf().canvas.draw_idle()

sline.on_changed(update)

plt.axis('scaled')
plt.show()

标签: matplotlibcollectionssliderfill

解决方案


您的代码大部分都在工作,但您有 2 个不幸的错误。

  • 您在函数中重新创建 PolyCollection 时忘记重新标记它 update(),以便可以在第二次删除它。
  • 您将重新创建 PolyCollection 的指令放在 for 循环中

以下代码似乎可以满足您的要求:

import matplotlib.pyplot as plt
import numpy as np
import matplotlib.animation
from matplotlib.widgets import Slider  # import the Slider widget

fig = plt.figure()

axcolor = 'lightgoldenrodyellow'
main_ax = plt.axes([0, .5, 10, 15])
slider_ax = plt.axes([0.2, 0.08, .7, .03], facecolor=axcolor)   

#Some constants
torad = np.pi/180
WAngle = 20.
xmax = 10

#Slider min max
s_min = 0
s_max = 60
s_init = WAngle

# set the current plot to main_ax
plt.sca(main_ax)

#Define and plot the triangle
plt.axes() #Select the main axis
plt.title('test')
plt.xlim(0,10)
plt.ylim(0,10)

#Now define the line, only need the second point, first point 0,0
Beta = WAngle
Bx = 10
By = Bx*np.tan(Beta * torad)

# Draw line and add to plot
xdat = [0, 10]
ydat = [0, By]
line = plt.Line2D(xdat, ydat,color='k')  #(x1,x2),(y1,y2)   
axis = plt.gca()
axis.add_line(line) 
fillbet = plt.fill_between(xdat, ydat, color="#539ecd",label="wedge")
sline = Slider(slider_ax, 'line', s_min, s_max, valinit=s_init) 

## def update(val): 
def update(val):
    myangle = sline.val
    By = Bx*np.tan(myangle * torad)
    xdat = [0, Bx]
    ydat = [0, By]
    line.set_xdata((0, Bx))
    line.set_ydata((0, By))
    for collection in axis.collections:
        if str(collection.get_label()) == "wedge":
            collection.remove()
    fillbet = plt.fill_between(xdat, ydat, color='#539ecd', label="wedge")
    fig.canvas.draw_idle()

sline.on_changed(update)

plt.axis('scaled')
plt.show()

推荐阅读