幻灯片更新后的Matplotlib fill_不重新绘制

幻灯片更新后的Matplotlib fill_不重新绘制,matplotlib,collections,slider,fill,Matplotlib,Collections,Slider,Fill,我画了一条简单的线y=mx+b,我只在第一个象限中围绕原点旋转它,我在这条线和x轴之间填充。我通过滑块更改直线的坡度。我对此进行了研究,为了在直线旋转时保持区域填充,似乎需要使用集合,这已经实现,但现在我进入了一个无限循环。具体地说,当我更改滑块时,填充区域是正确的,但仅针对滑块的一次更改。在此之后,它进入一个无限循环。任何帮助都将不胜感激。我的代码的主要部分如下: import matplotlib.pyplot as plt import numpy as np import matplot

我画了一条简单的线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()

您的代码基本正常,但有两个不幸的bug

在中重新创建多边形集合时,您忘了重新标记它 更新函数,以便可以第二次删除它 围绕 您将重新创建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()

您的代码基本正常,但有两个不幸的bug

在中重新创建多边形集合时,您忘了重新标记它 更新函数,以便可以第二次删除它 围绕 您将重新创建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()

如果您不希望多边形集合出现在图例中,而未对其进行标记,则还可以指定gid属性

我相应地更新了Diziet Asahi的代码:

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",gid="wedge") # <-- set `gid` instead of `label`
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 collection.get_gid() == "wedge": # <-- check `gid` instead of `label`
            collection.remove()
    fillbet = plt.fill_between(xdat, ydat, color='#539ecd', gid="wedge") # <-- set `gid` instead of `label`
    fig.canvas.draw_idle()

sline.on_changed(update)

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

如果您不希望多边形集合出现在图例中,而未对其进行标记,则还可以指定gid属性

我相应地更新了Diziet Asahi的代码:

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",gid="wedge") # <-- set `gid` instead of `label`
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 collection.get_gid() == "wedge": # <-- check `gid` instead of `label`
            collection.remove()
    fillbet = plt.fill_between(xdat, ydat, color='#539ecd', gid="wedge") # <-- set `gid` instead of `label`
    fig.canvas.draw_idle()

sline.on_changed(update)

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

尝试在更新函数结束时重新绘制画布plt.gcf.canvas.draw_idle。否则,请提供一个完整的可运行的代码,我编辑后,包括整个代码,其中包括您的建议,仍然给我相同的问题。谢谢您的时间。请尝试在更新功能结束时重新绘制画布plt.gcf.canvas.draw_idle。否则,请提供一个完整的可运行的代码,我编辑后,包括整个代码,其中包括您的建议,仍然给我相同的问题。谢谢你的时间。非常感谢,这让我发疯了。这正是我想要它做的。非常感谢,这让我发疯。这正是我想要它做的。