使用wxmplot.interactive模块绘图放大后如何获取对应区域的数据?
实现方案
wxmplot的interactive.plot()方法会返回PlotFrame实例,你可以通过该实例直接获取当前图表的轴范围,步骤如下:
- 保存绘图返回的
PlotFrame对象,后续通过它访问图表属性 - 调用
PlotFrame.panel.get_viewlimits()方法即可获取当前显示区域的(x最小值, x最大值, y最小值, y最大值) - 用拿到的x范围过滤原始DataFrame,即可得到选中区域的对应数据
以下是修改后的完整可运行代码,新增了保存按钮,点击即可将当前放大区域的对应数据导出为csv:
import wx import pandas as pd import wxmplot.interactive as wi import os class MyFrame(wx.Frame): def __init__(self): super().__init__(parent=None, title="Data Exploration Tool ") panel = wx.Panel(self) self.df = None self.title = '' self.plot_frame = None # 新增:保存绘图窗口实例 my_sizer = wx.BoxSizer(wx.HORIZONTAL) open_btn = wx.Button(panel, label='Open') open_btn.Bind(wx.EVT_BUTTON, self.OnOpen) my_sizer.Add(open_btn, 0, wx.ALL | wx.CENTER, 5) plot_btn = wx.Button(panel, label='Plot') plot_btn.Bind(wx.EVT_BUTTON, self.OnPlot) my_sizer.Add(plot_btn, 0, wx.ALL | wx.CENTER, 5) # 新增:保存选中区域数据的按钮 save_btn = wx.Button(panel, label='Save Selected Area') save_btn.Bind(wx.EVT_BUTTON, self.OnSaveSelected) my_sizer.Add(save_btn, 0, wx.ALL | wx.CENTER, 5) panel.SetSizer(my_sizer) self.Show() def OnPlot(self, event): # 把第一列转为datetime格式时直接存到df里,方便后续过滤 self.df.iloc[:,0] = pd.to_datetime(self.df.iloc[:, 0], format='%m/%d/%y %H:%M %p' ) x = self.df.iloc[:,0] for i in range(1, len(self.df.columns)): # 保存返回的PlotFrame实例 self.plot_frame = wi.plot(x, self.df.iloc[:, i], show_legend=True, title=self.title, wintitle=self.title) def OnOpen(self, event): defDir='' defFile='' fileDialog = wx.FileDialog(self, "Open CSV file", defDir, defFile, wildcard="(*.csv;*.xlsx)|*.csv;*.xlsx", style=wx.FD_OPEN | wx.FD_FILE_MUST_EXIST) if fileDialog.ShowModal() == wx.ID_CANCEL: return pathname = fileDialog.GetPath() print(pathname) self.df = pd.read_csv(pathname, skiprows=12, parse_dates=True) self.title = os.path.basename(pathname) # 新增:保存选中区域数据的方法 def OnSaveSelected(self, event): if not self.df or not self.plot_frame: wx.MessageBox("请先打开文件并绘图", "提示", wx.OK | wx.ICON_WARNING) return # 获取当前显示区域的轴范围 x_min, x_max, y_min, y_max = self.plot_frame.panel.get_viewlimits() # 过滤x范围对应的数据 mask = (self.df.iloc[:,0] >= x_min) & (self.df.iloc[:,0] <= x_max) filtered_df = self.df[mask] # 选择保存路径 save_dialog = wx.FileDialog(self, "保存选中区域数据", wildcard="CSV文件(*.csv)|*.csv", style=wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT) if save_dialog.ShowModal() == wx.ID_CANCEL: return save_path = save_dialog.GetPath() filtered_df.to_csv(save_path, index=False) wx.MessageBox(f"数据已保存到{save_path}", "保存成功", wx.OK) if __name__ == '__main__': app = wx.App() frame = MyFrame() app.MainLoop()
如果需要拖拽选中区域后自动触发数据获取,可以给坐标轴绑定范围变化事件,在OnPlot方法里添加如下代码即可:
# 绑定x轴范围变化事件,每次放大/缩小/平移都会触发指定的回调方法 self.plot_frame.panel.axes.callbacks.connect('xlim_changed', 你的回调方法名)
内容的提问来源于stack exchange,提问作者Maureen McCleary
相关产品推荐
相关产品推荐

