matplotlib LineCollection、PatchCollection重绘

mtb9vblg  于 2023-10-24  发布在  其他
关注(0)|答案(1)|浏览(121)

我正在尝试使用matplotlib绘图,其中LineCollectionPatchCollection(圆)可以通过滑块进行更改:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.collections import LineCollection, CircleCollection, PatchCollection
from matplotlib.patches import Circle
from ipywidgets import interact, FloatSlider, Layout
%matplotlib notebook
fig = plt.figure()
ax = plt.axes()
lines = LineCollection(np.array([[[0,0],[1,1]]]))
circles = PatchCollection([Circle((.5,.5),.5)])
ax.add_collection(lines)
ax.add_collection(circles)
#lines.set_segments([[[0,1],[1,0]]])
#circles.set_paths([Circle((.5,.5),.1)])
interact(lambda s: circles.set_paths([Circle((.5,.5),s)]),
     s = FloatSlider(min = 0, max = .5, step=.01))
interact(lambda t: lines.set_segments([[[0,t],[1,1-t]]]),
     t = FloatSlider(min = 0, max = 1, step=.01))

它对LineCollection工作正常,但更改PatchCollection的参数不会使图形被重绘。更改PatchCollection的函数以包括figs.canvas.draw()解决了这个问题,所以我认为PatchCollection.set_paths()不像LineCollection.set_segments()不会触发重绘。然而,在注解行circles.set_paths()does 似乎触发了重画。有人能解释一下发生了什么吗?如果可能的话,我希望有一致的行为。

oknrviil

oknrviil1#

我想,这更接近于你想要的工作:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.collections import LineCollection, CircleCollection, PatchCollection
from matplotlib.patches import Circle
from ipywidgets import interact, FloatSlider, Layout
%matplotlib notebook
fig = plt.figure()
ax = plt.axes()
lines = LineCollection(np.array([[[0,0],[1,1]]]))
circles = PatchCollection([Circle((.5,.5),.5)])
ax.add_collection(lines)
ax.add_collection(circles)
#lines.set_segments([[[0,1],[1,0]]])
#circles.set_paths([Circle((.5,.5),.1)])
def two(s,t):
    return (circles.set_paths([Circle((.5,.5),s)]),lines.set_segments([[[0,t],[1,1-t]]]))

_ = interact( two,
    s = FloatSlider(value = 0.1, min = 0, max = .5, step=.01),
    t = FloatSlider(value = 0,min = 0, max = 1, step=.01)
)

我所做的主要调整是使用一个interact()函数来创建UI并允许交互式地控制数据。
您可以根据需要组合合并和与每个小部件相关的功能;但是,文档表明它们应该在interact()下定向。
依据:

  • 主要是here,其中它们涉及多个函数
  • 主要与here结合,其中包含多个小部件和函数的更多示例,请参见示例中的def three
  • here用于初始设置

注意,我不清楚你想要的圆的初始值是什么,所以你可能需要自己调整。
至于我的评论,你没有遵循文档使用ipywidgets与matplotlib的结合,发现在“ Flink 和跳跃输出”。(注意,我认为该页面是如此之长,或包含一些CSS,使它不能直接链接到部分,它应该在我的经验,所以你可能需要向下滚动找到它。YMMV。).
特别地,在该示例中,所有图定义处理都被构建到interact()所针对的单个图函数中。
我仍然没有将您的代码转换为这种方法,因为也许您是对的,它不是严格必要的(正如我在最初的评论中试图建议的那样),而且此时它更繁重。
我会说,我更能够轻松地将合并与构建代码的图表结合起来,参见here for the code (first example, specifically)。如果你想看到它的实际效果,那么去here并单击launch binder,然后在会话启动时从列表中选择适当的笔记本,特别是“通过widget可定制的3D散点图”。因为你使用的是经典的笔记本界面,你会想去'帮助'菜单,并选择启动经典笔记本电脑切换到尝试我上面说的。(注意当在这样的会话中运行时,如果你想要更像我的例子或ipywidgets的例子与%matplotlib notebook工具栏提供的东西一起工作,你会想要使用%ipympl,就像这里所说的那样。奇怪的是,你的代码在这样的会话中可以像%matplotlib notebook一样工作,而不需要改变它。另一方面,我的例子在%matplotlib notebook下有点中断。我说的“有点中断”是指现在当我改变到%matplotlib notebook并重新启动内核并运行绘图代码时,我没有看到图,但是当我调整一个滑块时,我可能会再次看到我的例子的图。对于来自ipywidgets文档的matplotlib的例子,我第一次调整其中一个滑块时看到图,但是当我再次调整时它消失了(?).所以我建议%matplotlib inline or %matplotlib ipympl与我引用的任何代码示例一起出现在该会话中。 你会注意到,如果你运行我的例子(或ipywidgets与matplotlib结合的例子),你不会看到任何像(None, None)`这样的“工件”,我在编辑后的版本下面看到的,如果你的输出。我链接到的代码示例是自包含的,所以你应该能够复制代码并在你正在工作的地方尝试它,以测试它在你正在工作的地方表现良好。

相关问题