互动和绘图 quiverin Python Jupyter Notebook

Interact and plot quiverin Python Jupyter Notebook

我想使用交互功能创建滑块,用户可以在其中输入矢量坐标并绘制这些坐标。问题是改变输入值并不能生成新的图形,是否可以让它工作?

我正在使用 jupyter notebook。我的代码

import panel as pn
import numpy as np
import matplotlib.pyplot as plt
from panel.interact import interact, interactive, fixed, interact_manual
pn.extension()

def f(u1,u2,v1,v2):
    plt.clf()
    vetores = np.array([[0,0,u1,u2], [u1,u2,v1,v2]])
    X, Y, U, V = zip(*vetores)
    plt.figure()
    ax = plt.gca()
    ax.quiver(X, Y, U, V, angles='xy', scale_units='xy', scale=1, color = ['r','g','b'])
    ax.set_xlim([min(-1,u1-1, v1-1), max(u1+v1+1, v1+1)])
    ax.set_ylim([min(-1,u2-1, v2-1), max(u2+v2+1, v2+1)])
    plt.show()
    
interact(f, u1=2, u2=0, v1=2, v2=3)

您可以使用ipywidgets 交互式绘图。 Matplotlib 有箭袋:

from ipywidgets import interactive
import matplotlib.pyplot as plt
import numpy as np

def f(u1,u2,v1,v2):
    plt.figure()
    vetores = np.array([[0,0,u1,u2], [u1,u2,v1,v2]])
    X, Y, U, V = zip(*vetores)
    plt.quiver(X, Y, U, V, angles='xy', scale_units='xy', scale=1, color = ['r','g','b'])
    ax = plt.gca()
    ax.set_xlim([min(-1,u1-1, v1-1), max(u1+v1+1, v1+1)])
    ax.set_ylim([min(-1,u2-1, v2-1), max(u2+v2+1, v2+1)])
    plt.show()

interactive_plot = interactive(f, u1=2, u2=0, v1=2, v2=3)
interactive_plot

您的代码已改编为
它在从底部的 link 启动的 Jupyter 会话中的笔记本中工作。

它也适用于通过 the TryJupyter site (tested in sessions launched from both JupyterLab and the classic notebook) or the holoviz panel MyBinder launch here 启动的 Jupyter 会话中的笔记本。



使用面板

或者在here and returning a proper Matplotlib figure based on here上半部分的基础上结合Matplotlib使用Panel:

import panel as pn
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np

pn.extension()

title = '## Quiver Panel controller'
def f(u1,u2,v1,v2):
    pl = plt.figure()
    vetores = np.array([[0,0,u1,u2], [u1,u2,v1,v2]])
    X, Y, U, V = zip(*vetores)
    pl.add_subplot(111).quiver(X, Y, U, V, angles='xy', scale_units='xy', scale=1, color = ['r','g','b'])
    ax = plt.gca()
    ax.set_xlim([min(-1,u1-1, v1-1), max(u1+v1+1, v1+1)])
    ax.set_ylim([min(-1,u2-1, v2-1), max(u2+v2+1, v2+1)])
    plt.close(pl)
    return pl

interact = pn.interact(f, u1=2, u2=0, v1=2, v2=3)


pn.Row(
    pn.Column(title, interact[0], sizing_mode="fixed", width=300),
    interact[1]
)
#interact # use this if don't want side-by-side

这个例子中的布局更好,但是上面选项中使用的ipywidgets也可以用来排列控件side-by-side,参见here for an example

我想有一种方法可以让它更简单,而不是使用基于 this and associated note in FAQ:

return plt.gcf()

"A: Matplotlib pyplot users often use %matplotlib inline, which shows plots as a "side effect" in a Jupyter notebook, rather than using the cell's return value like Python literals and other objects do. Panel callbacks like those accepted for pn.interact() work on the return value of the callback, which is then provided as the return value of the cell, and thus directly display without any requirements for side effects. So, if you create a Matplotlib plot that would magically appear via %matplotlib inline, for Panel you need to ensure that the callback actually returns a value, rather than counting on this side effect. Specifically, if you have a callback with some Matplotlib plotting calls, you can add return plt.gcf() to your callback to make the current figure be returned, which will ensure that your plot is displayed properly."

但是,我无法轻易找到有效的组合,也没有看到两个图。事实上,只是尝试 the example code there results in two plots as well, only the upper one updating via the slider. The approach earlier in that thread 不会产生这样的工件。