想通过python做一个界面,显示坐标轴,且横坐标很长,需要通过滚动条滑动,我是通过tkinter工具做的,它是将坐标轴(plt.figure
)嵌入到画布中(FigureCanvasTkAgg
),通过滚动(Scrollbar
)画布(Canvas
)实现这个功能。找了很多资料,都没有看到如何设置坐标轴与画布的相对位置,且滚动条的滚动范围也并不是按照scrollregion
参数设置,这两个问题困扰了我好几天,终于通过多次设置尺寸,找出了它们的规律。
图中: X1为frame宽度,
X2为画布宽度,
那么滚动轴滚动范围为:2*x2-x1
红色为坐标轴,默认在中心,不知道具体尺寸,但是可以通过fig.add_axes([0,0.1,1,0.8])设置具体位置,参数:[坐标轴距离左边,坐标轴距离下边,坐标轴宽度,坐标轴高度] 数值范围为(0, 1),通过百分比计算
下面将代码贴上,供大家参考:
from tkinter.constants import BOTH, BOTTOM
import numpy as np
import tkinter as tk
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.pyplot import MultipleLocator, axis, colorbar, figure
root = tk.Tk()#创建tk窗口
root.geometry('800x400')#设置窗口尺寸
root.resizable(500,300)#设置窗口显示时左上角在屏幕中的位置
frame1 = tk.Frame(root,width=50,height=350)#建立左侧框架,放置左侧y轴
frame1.place(x=0,y=0)#根据具体坐标放置,tk窗口放大后,保持固定尺寸,不会动态变化
frame2 = tk.Frame(root,width=650,height=400)#建立中间框架,放置x轴
frame2.place(x=50,y=0)
frame3 = tk.Frame(root,width=100,height=350)#建立右侧框架,放置右侧y轴
frame3.place(x=700,y=0)
sb=tk.Scrollbar(root, orient='horizontal')#建立水平滚动条控件
fig = plt.figure(1,figsize=(2,1))#建立绘制坐标轴fig
#fig.add_axes()
fig.add_axes([0,0.1,1,0.8])# [距离左边,下边,坐标轴宽度,坐标轴高度] 范围(0, 1)
rect = fig.patch#为fig添加一个矩形框
rect.set_facecolor('red')#矩形框内填充为红色
number = 100
plt.plot(np.random.rand(number))#横坐标范围为0~number,纵坐标为随机数
x_majot_locator=MultipleLocator(1)#坐标轴单位长度为1
ax=plt.gca()#获取fig中的坐标轴
ax.xaxis.set_major_locator(x_majot_locator)#设置坐标轴单位长度
ax.spines['left'].set_color('none')#将左侧纵坐标轴取消显示
ax.spines['right'].set_color('none')#将右侧纵坐标轴取消显示
plt.xlim(-0.5,number+0.5)#设置x轴显示范围
plt.ylim(-0.05,1.05)
plt.grid()
canvas = FigureCanvasTkAgg(fig, master=frame2)#将fig嵌入画布中,布局方式为pack()
#canvas.get_tk_widget().config(scrollregion=canvas.get_tk_widget().bbox("all"))
wid = number*10*7/2
canvas.get_tk_widget().config(width=wid,height=350,bg='yellow')#设置画布属性:宽,高,背景
#设置画布x轴支持滚动,滚动范围为scrollregion包含的矩形范围,其中x2大小右下面的线性方程获得,
#wid表示画布的宽度,650是画布所在frame的宽度
x2 = 2*wid-650
canvas.get_tk_widget().config(xscrollcommand=sb.set,scrollregion=(0,0,x2,350))
canvas.get_tk_widget().place(x=0,y=0)#放置画布
#canvas.get_tk_widget().pack()
canvas.draw()#绘制画布
sb.pack(side=BOTTOM,fill=BOTH)#放置滚动条
sb.config(command=canvas.get_tk_widget().xview)#配置滚动条关联画布x轴方向
fig1 = plt.figure()
fig1.add_axes([49/50,0.1,0.1,0.8])
plt.plot()
plt.ylim(-0.05,1.05)
plt.ylabel("values")
plt.xticks([])
plt.grid()
canvas1 = FigureCanvasTkAgg(fig1, master=frame1)
canvas1.get_tk_widget().config(width=50,height=350,bg='white')
canvas1.get_tk_widget().pack()
canvas1.draw()
fig3 = plt.figure()
fig3.add_axes([0,0.1,1/50,0.8])
plt.plot()
plt.ylim(-0.05,1.05)
plt.xticks([])
plt.grid()
ax3=plt.gca()
ax3.spines['left'].set_color('none')
canvas3 = FigureCanvasTkAgg(fig3, master=frame3)
canvas3.get_tk_widget().config(width=50,height=350,bg='white')
canvas3.get_tk_widget().pack()
canvas3.draw()
root.update()#更新窗口
root.mainloop()
实现的效果如下: