浏览器中的Python交互式绘图:拖放任意元素

2024-06-13 02:36:38 发布

您现在位置:Python中文网/ 问答频道 /正文

我的后端是Python,我正在尝试在web浏览器中创建一个交互式绘图,用户可以在绘图中拖放元素。然后,计划使用一些JS钩住“drop”事件,这些JS更新表单中的值并提交表单,这将导致后端更新绘图

到目前为止,我一直在使用mpld3,但我没有投资于它。我愿意接受使用其他软件包(如Plotly或Bokeh)的解决方案

我所寻找的与this mpld3 example非常相似,只是我想允许用户拖动点以外的对象。具体来说,我想创建一些垂直和水平线,并允许用户水平和垂直拖动这些线,如下图所示:

enter image description here

到目前为止,我已经对mpld3插件进行了调整,使其能够实际使用最新版本的d3.js,并且我能够拖动这些点(请参见gist)。但是,我无法调整插件,使垂直线像示例中的点一样可以拖动

我的第一个想法是

lines = ax.vlines(xdata,min(ydata),ydata)
plugins.connect(fig, DragPlugin(lines))

vlines()返回一个matplotlib.collections.LineCollection项,我不知道如何访问其中的单个行。我试图简单地修改__init__if isinstance(object, mpl.lines.Line2D))中的类型检查,使其更为宽松,但这不起作用

我的下一个想法是使用ax.plot()来画线:

lines = []
for i in range(len(xdata)):
    from_xy = (xdata[i],min(ydata))
    to_xy = (xdata[i],ydata[i])
    xs = from_xy[0],to_xy[0]
    ys = from_xy[1],to_xy[1]
    lines.append(ax.plot(xs,ys, 'k-')[0])

在本例中,列表lines包含matplotlib.lines.Line2D对象,我认为在mpld3中单独操作这些对象比LineCollection更容易。然而,该插件似乎是为了将整个红点集作为Line2D对象来处理的(如有不可见边的多边形链,如果你明白我的意思的话)。这是我从字符串'pts'用于查找点的mpld3 id这一事实得出的结论。但是,仅将Line2D对象传递给DragPlugin并不起作用:

# don't use the suffix:
def __init__(self, object):
        self.dict_ = {"type": "drag","id": utils.get_id(object)}

# after defining `lines` as above:
plugins.connect(fig, DragPlugin(lines[0]))

我在浏览器控制台中获得以下信息:

Uncaught TypeError: obj.elements(...).data(...).style is not a function

将在JS的以下部分引发:

obj.elements()
           .data(obj.offsets)
           .style("cursor", "default")
           .call(drag);

但我不知道JS在做什么,插件中也没有记录

我需要的另一件事是限制垂直线只能水平拖动,而水平线则相反。但首先,我想让拖动线发挥作用


Tags: 对象用户from插件绘图objectjsax