从图表中选择点 matplotlib
目前我有一个散点图,我可以放大、移动等等。
我还想做的是能够在图上选择一些特定的点,然后把这些选中的点存储到一个数组里。
在matplotlib中有没有什么特别的函数可以用来实现这个功能呢?
任何帮助都非常感谢!
我的代码
import os
import wx
import numpy as nump
import matplotlib
matplotlib.use('WXAgg')
import matplotlib.figure as fg
import matplotlib.backends.backend_wxagg as wxagg
class MyFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, -1, 'Title')
self.create_main_panel()
self.draw_figure()
def create_main_panel(self):
self.panel = wx.Panel(self)
self.dpi = 100
self.fig = fg.Figure((5.0, 4.0), dpi=self.dpi)
self.canvas = wxagg.FigureCanvasWxAgg(self.panel, -1, self.fig)
self.axes = self.fig.add_subplot(111)
self.toolbar = wxagg.NavigationToolbar2WxAgg(self.canvas)
self.vbox = wx.BoxSizer(wx.VERTICAL)
self.vbox.Add(self.canvas, 1, wx.LEFT | wx.TOP | wx.GROW)
self.vbox.AddSpacer(25)
self.vbox.Add(self.toolbar, 0, wx.EXPAND)
self.panel.SetSizer(self.vbox)
self.vbox.Fit(self)
def draw_figure(self):
self.axes.clear()
x, y = [2,3,4,5]
self.axes.scatter(x, y)
self.canvas.draw()
def on_exit(self, event):
self.Destroy()
if __name__ == '__main__':
app = wx.PySimpleApp()
app.frame = MyFrame()
app.frame.Show()
app.MainLoop()
1 个回答
2
下面的代码提供了一种可能的解决方案。基本的方法可以总结如下:
- 首先,设置一个处理程序来处理
pick_event
,这个处理程序会把选中的数据索引不断添加到一个列表self._picked_indices
中。 - 然后,设置一个
key_press_event
的处理程序,当用户按下escape
键时,会清空self._picked_indices
列表。 - 方法
MyFrame.picked_points
会返回当前选中点的坐标列表。如果还没有选中任何点,这个方法会返回None
(你可以修改它,让它在这种情况下返回一个空列表,这样更方便)。
这样,你就可以通过点击来不断选择点。如果你想重新开始,只需按下 escape
键,然后再开始选择。
#! /usr/bin/env python
import os
import wx
import numpy as nump
import matplotlib
matplotlib.use('WXAgg')
import matplotlib.figure as fg
import matplotlib.backends.backend_wxagg as wxagg
class MyFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, -1, 'Title')
self.create_main_panel()
self.draw_figure()
self._is_pick_started = False
self._picked_indices = None
def create_main_panel(self):
self.panel = wx.Panel(self)
self.dpi = 100
self.fig = fg.Figure((5.0, 4.0), dpi=self.dpi)
self.canvas = wxagg.FigureCanvasWxAgg(self.panel, -1, self.fig)
self.axes = self.fig.add_subplot(111)
self.toolbar = wxagg.NavigationToolbar2WxAgg(self.canvas)
self.vbox = wx.BoxSizer(wx.VERTICAL)
self.vbox.Add(self.canvas, 1, wx.LEFT | wx.TOP | wx.GROW)
self.vbox.AddSpacer(25)
self.vbox.Add(self.toolbar, 0, wx.EXPAND)
self.panel.SetSizer(self.vbox)
self.vbox.Fit(self)
self.fig.canvas.mpl_connect('pick_event', self.on_pick)
self.fig.canvas.mpl_connect('key_press_event', self.on_key)
def draw_figure(self):
self.axes.clear()
self._x_data, self._y_data = [[2,3], [4,5]]
self.axes.scatter(self._x_data, self._y_data, picker=5)
self.canvas.draw()
def on_exit(self, event):
self.Destroy()
def picked_points(self):
if self._picked_indices is None:
return None
else:
return [ [self._x_data[i], self._y_data[i]]
for i in self._picked_indices ]
def on_pick(self, event):
if not self._is_pick_started:
self._picked_indices = []
self._is_pick_started = True
for index in event.ind:
if index not in self._picked_indices:
self._picked_indices.append(index)
print self.picked_points()
def on_key(self, event):
"""If the user presses the Escape key then stop picking points and
reset the list of picked points."""
if 'escape' == event.key:
self._is_pick_started = False
self._picked_indices = None
return
if __name__ == '__main__':
app = wx.PySimpleApp()
app.frame = MyFrame()
app.frame.Show()
app.MainLoop()