gpt4 book ai didi

python - (wxpython) 使 matplotlib NavigationToolbar 为滚动面板内的图形静态

转载 作者:行者123 更新时间:2023-12-01 01:04:00 28 4
gpt4 key购买 nike

我有一个 Matplotlib 图形,其中有很多子图,需要 ScrolledPanel。现在,我想要一个用于图形的导航工具栏,当图形面板滚动时,它保持静态。我尝试将其添加到 Canvas 父级之外的另一个面板,但这不起作用(导航工具栏仅保留在 Canvas 父级内)。
有没有办法让 matplotlib 导航工具栏保持静态,但使 Canvas 的其余部分可滚动?
这是我的完整代码:

import wx
import wx.lib.scrolledpanel

import matplotlib
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas
from matplotlib.backends.backend_wxagg import NavigationToolbar2WxAgg as NavigationToolbar
from matplotlib.figure import Figure

import wx.lib.inspection

matplotlib.use('WXAgg')


class PlotDemoApp(object):
def __init__(self, data):
self.app = wx.App()
self.frame = PlotCanvas(None, -1, "PlotCanvas", data)
self.frame.Show(True)
wx.lib.inspection.InspectionTool().Show()
self.app.MainLoop()


class PlotCanvas(wx.Frame):
def __init__(self, parent, wxid, title, data):
wx.Frame.__init__(self, parent, wxid, title)

self.box_main = wx.BoxSizer(wx.VERTICAL)

panel_lower = wx.lib.scrolledpanel.ScrolledPanel(self, size=(2500,-1))
panel_lower.SetupScrolling()
panel_lower.SetBackgroundColour("White")
self.box_lower = wx.BoxSizer(wx.HORIZONTAL)

box_local = wx.BoxSizer(wx.VERTICAL)
plt = Figure(figsize=(95,10))
num_columns = len(data.columns)
axes_1 = plt.add_subplot(1, num_columns, 1)
data_numpy = data[data.columns[0]].to_numpy()
depth = data.index.to_numpy()
plt.gca().invert_yaxis()
plt.subplots_adjust(left=0.01, right=1.00, top=0.95, bottom=0.05)
axes_1.plot(data_numpy, depth)
for i in range(1, num_columns):
axes_tmp = plt.add_subplot(1, num_columns, i+1, sharey=axes_1)
axes_tmp.set(xlabel=data.columns[i], ylabel='Depth', title='Depth vs ' + data.columns[i])

data_numpy = data[data.columns[i]].to_numpy()

plt.gca().invert_yaxis()
axes_tmp.plot(data_numpy, depth)
canvas = FigureCanvas(panel_lower, -1, plt)
canvas.draw()
box_local.Add(canvas, 1, wx.EXPAND)
panel_nav = wx.Panel(self)
box_nav = wx.BoxSizer(wx.HORIZONTAL)
toolbar = NavigationToolbar(canvas)
box_nav.Add(toolbar)
panel_nav.SetSizer(box_nav)
toolbar.Realize()
self.box_main.Add(panel_nav, 0, wx.CENTER)
self.box_lower.Add(box_local, 1, wx.EXPAND)

self.box_main.Add(panel_lower, 1, wx.EXPAND)
panel_lower.SetSizer(self.box_lower)
self.SetSizer(self.box_main)
self.box_main.Layout()

data 这里是一个 pandas 数据框
样本数据:

| index | BS   | CAL  |
|-------|------|------|
| 162 | 17.5 | 17.4 |
| 163 | 17.8 | 17.7 |
| 164 | 17.8 | 17.9 |

最佳答案

希望这就是您所追求的,或者至少为您指明了正确的方向。

matplotlib 导航工具栏似乎与绘图本身焊接在一起,但它可以隐藏。

虽然它保持隐藏状态,但它的功能仍然可用,因此我们可以创建自己的工具栏并为其分配隐藏工具栏中的功能。

像这样:

import wx
import wx.lib.scrolledpanel as scrolled
import pandas as pd
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas
from matplotlib.backends.backend_wxagg import NavigationToolbar2WxAgg as NavigationToolbar
from matplotlib.figure import Figure

# images in /usr/share/matplotlib/mpl-data/images
# Your system may differ!

class PlotPanel(scrolled.ScrolledPanel):
def __init__(self,parent):
scrolled.ScrolledPanel.__init__(self, parent)
self.SetupScrolling(scroll_x=True, scroll_y=True, scrollToTop=False, scrollIntoView=False)
self.ShowScrollbars(True,True)
self.plt = Figure(figsize=(95,10))
self.canvas = FigureCanvas(self,-1, self.plt)
self.toolbar = NavigationToolbar(self.canvas)

#Hide the Matplotlib toolbar because we are going to create own own
#but use the functions of this toolbar.
self.toolbar.Hide()

def plot(self):
d = {'BS':[17.54,17.55,17.54,17.53,17.55,17.54],'CAL':[17.46,17.47,17.49,17.44,17.47,17.49]}
data = pd.DataFrame(d, index=['1','2','3','4','5','6'])

num_columns = len(data.columns)
axes_1 = self.plt.add_subplot(1, num_columns, 1)
#data_numpy = data[data.columns[0]].to_numpy() # My version of pandas doesn't have .to_numpy()
data_numpy = data[data.columns[0]]
#depth = data.index.to_numpy()
depth = data.index
self.plt.gca().invert_yaxis()
self.plt.subplots_adjust(left=0.01, right=0.50, top=0.95, bottom=0.05)
axes_1.plot(data_numpy, depth)
for i in range(0, num_columns):
axes_tmp = self.plt.add_subplot(1, num_columns, i+1, sharey=axes_1)
axes_tmp.set(xlabel=data.columns[i], ylabel='Depth', title='Depth vs ' + data.columns[i])

#data_numpy = data[data.columns[i]].to_numpy()
data_numpy = data[data.columns[i]]

self.plt.gca().invert_yaxis()
axes_tmp.plot(data_numpy, depth)
self.canvas.draw()
self.SetSize(self.canvas.GetSize())

class TestFrame(wx.Frame):
def __init__(self,parent,title):
wx.Frame.__init__(self,parent,title=title,size=(600,600))

self.p1 = PlotPanel(self)

#Create our own toolbar
toolbar = self.CreateToolBar(style=wx.TB_HORIZONTAL|wx.TB_DOCKABLE|wx.TB_TEXT)
hometool = toolbar.AddTool(wx.ID_ANY, 'Home', wx.Bitmap('/usr/share/matplotlib/mpl-data/images/home.png'))
backtool = toolbar.AddTool(wx.ID_ANY, 'Back', wx.Bitmap('/usr/share/matplotlib/mpl-data/images/back.png'))
fwdtool = toolbar.AddTool(wx.ID_ANY, 'Forward', wx.Bitmap('/usr/share/matplotlib/mpl-data/images/forward.png'))
pantool = toolbar.AddTool(wx.ID_ANY, 'Pan', wx.Bitmap('/usr/share/matplotlib/mpl-data/images/move.png'))
zoomtool = toolbar.AddTool(wx.ID_ANY, 'Zoom', wx.Bitmap('/usr/share/matplotlib/mpl-data/images/zoom_to_rect.png'))
subtool = toolbar.AddTool(wx.ID_ANY, 'Subplots', wx.Bitmap('/usr/share/matplotlib/mpl-data/images/subplots.png'))
savetool = toolbar.AddTool(wx.ID_ANY, 'Save', wx.Bitmap('/usr/share/matplotlib/mpl-data/images/filesave.png'))

self.Bind(wx.EVT_TOOL, self.home, hometool)
self.Bind(wx.EVT_TOOL, self.back, backtool)
self.Bind(wx.EVT_TOOL, self.fwd, fwdtool)
self.Bind(wx.EVT_TOOL, self.pan, pantool)
self.Bind(wx.EVT_TOOL, self.zoom, zoomtool)
self.Bind(wx.EVT_TOOL, self.sub, subtool)
self.Bind(wx.EVT_TOOL, self.save, savetool)
toolbar.Realize()

sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(self.p1,1,wx.EXPAND,10)
self.statusbar=self.CreateStatusBar()
self.SetSizer(sizer)
self.Show()
self.plot()

#Self defined Navigation Toolbar controls used to call hidden matplotlib Toolbar functions
def home(self,event):
self.statusbar.SetStatusText("Home")
self.p1.toolbar.home()
# Also scroll panel to start position
self.p1.Scroll(0,0)

def back(self,event):
self.statusbar.SetStatusText("Back")
self.p1.toolbar.back()

def fwd(self,event):
self.statusbar.SetStatusText("Fwd")
self.p1.toolbar.forward()

def pan(self,event):
self.statusbar.SetStatusText("Pan")
self.p1.toolbar.pan()

def zoom(self,event):
self.statusbar.SetStatusText("Zoom")
self.p1.toolbar.zoom()

def sub(self,event):
self.statusbar.SetStatusText("Subplots")
self.p1.toolbar.configure_subplots(event)

def save(self,event):
self.statusbar.SetStatusText("Save")
self.p1.toolbar.save_figure()

def plot(self):
self.p1.plot()

app = wx.App(redirect=False)
frame = TestFrame(None,"Plot in Scrolled panel with replacement Navigation")
app.MainLoop()

enter image description here

您会注意到我将替换的工具栏设置为可停靠,因此我可以将工具栏移动到屏幕上的任何位置。它是可重新连接的。

enter image description here

因为我们正在定义自己的工具栏,所以它可以位于我们想要的任何位置,只需查看 wx.Toolbar 的选项即可。
在这里,我丢失了文本并使其垂直。

enter image description here

关于python - (wxpython) 使 matplotlib NavigationToolbar 为滚动面板内的图形静态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55549651/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com