问题 matplotlib交互式图形(在图形上手动绘制线条)


我使用matplotlib成功绘制了一组日期排序数据(X轴是日期)。但是,我希望能够 手动 在绘制的图形上从一个(date1,y1)到另一个(date2,y2)绘制线条。

我似乎无法找到任何显示如何做到这一点的例子 - 或者确实如果它甚至是可行的。

总而言之,这就是我想要做的:

  1. 在绘制的图形上绘制一组线条
  2. 将手动绘制的行数据保存到文件
  3. 从文件加载手动绘制的行数据(以重新创建图形)
  4. 理想情况下,我想存储关于绘制线条的“元数据”(例如颜色,线宽等)

有人可以发布一个骨架片段(最好带有更多信息的链接),以显示我如何开始实现这一点(主要要求是能够在图形上手动绘制线条,然后将线条保存/加载到绘图中)。

注意: 通过'手动',我的意思是能够通过单击一个点来绘制线条,然后单击绘制图形中的另一个点。在两点之间画一条线(或者只是点击一个点并在绘制的图形上的另一个点拖动并释放鼠标)

[[更新]]

dawe,非常感谢你提供的代码片段。这允许我做我想做的事情 - 但是,一旦在画布上绘制线条(在第二次鼠标点击之后),GUI崩溃并且我在控制台上收到此警告消息:

/usr/local/lib/python2.6/dist-packages/matplotlib/backend_bases.py:2192: DeprecationWarning: Using default event loop until function specific to this GUI is implemented
  warnings.warn(str,DeprecationWarning)

你知道是什么导致了这个警告和突然的程序终止吗?

此外,是否可以在图表上绘制多条线? (我猜这将涉及编写某种事件处理程序,它将实例化一个linedrawer变量)。目前,在'app'突然终止之前,我有机会只画一行。


11698
2018-02-03 23:38


起源

“手动”是模棱两可的(以粗体显示并不能解决模糊性)。你的意思是手动点击一个点然后点击另一个点,或者你的意思是手动输入一些东西?或者要么足够? - DSM
@DSM:澄清了问题中使用的'手动'的含义。 HTH - Homunculus Reticulli
matplotlib.sourceforge.net/api/widgets_api.html 可能是开始的地方。 - David Z
我建议看看 事件处理 例子。 - DSM
对我来说,手动意味着拿铅笔并开始绘画。试着准确一点,我会尽量拒绝在模棱两可的情况下猜测的诱惑(我在澄清后删除了我的答案)。 - joaquin


答案:


我会写这样的东西:

import matplotlib.pyplot as plt
class LineDrawer(object):
    lines = []
    def draw_line(self):
        ax = plt.gca()
        xy = plt.ginput(2)

        x = [p[0] for p in xy]
        y = [p[1] for p in xy]
        line = plt.plot(x,y)
        ax.figure.canvas.draw()

        self.lines.append(line)

运用 ginput() 你可以避免更复杂的事件处理。它的“工作方式”是你绘制的东西:

plt.plot([1,2,3,4,5])
ld = LineDrawer()
ld.draw_line() # here you click on the plot

要将行数据保存/加载到文件,您可以轻松实现使用的方法 pickle 要么 shelve。您还可以通过该方法传递必要的元数据 draw_line()


10
2018-02-10 10:24



+1代码让我(几乎)。这是 究竟我想做什么!非常感谢!。当前片段存在一些问题(除了小命名空间问题)。当我运行脚本时,它允许我通过单击(就像我想要的那样)在画布上绘制 - 但是,在第二次鼠标单击时,绘制线条时,GUI会立即崩溃,并且我在控制台上有一个警告按钮(请参阅我更新的问题) - Homunculus Reticulli
确保在IPython pylab模式下运行此代码: ipython -pylab。这为您正确使用的后端设置了事件循环,使这种快速和脏的交互工作成为可能。 - dawe