在此先感谢您的宝贵帮助! 我无法在tkinter中嵌入matplotlib。你可以引导我吗?
我已经导入了所有正确的模块 matplotlib.pyplot,matplotlib.dates,FigureCanvasTkAgg,NavigationToolbar2Tk,key_press_handler,Figure等。
然后...
root = tk.Tk()
root.wm_title("Embedding in Tk")
def bytespdate2num(fmt, encoding ='utf-8'):
strconverter = mdates.strpdate2num(fmt)
def bytesconverter(b):
s = b.decode(encoding)
return strconverter(s)
return bytesconverter
def graph_data(stock):
fig = plt.figure()
ax1 = plt.subplot2grid((1,1), (0,0))
url_stock = 'https://pythonprogramming.net/yahoo_finance_replacement'
source_code = urllib.request.urlopen(url_stock).read().decode()
stock_data = []
source_split = source_code.split('\n')
for line in source_split[1:]:
line_split = line.split(',')
if len(line_split) == 7:
if 'values' not in line and 'labels' not in line:
stock_data.append(line)
date, closep, highp, lowp, openp, adj_closep, volume = np.loadtxt(stock_data, delimiter =',', unpack= True, converters={0: bytespdate2num('%Y-%m-%d')})
ax1.plot_date(date, closep, '-', label ='closing price')
ax1.axhline(closep[0], color='k', linewidth = 2)
ax1.fill_between(date, closep, closep[0], where=(closep > closep[0]), facecolor='g', alpha=0.5)
ax1.fill_between(date, closep, closep[0], where=(closep < closep[0]), facecolor ='r', alpha = 0.5)
ax1.xaxis.label.set_color('c')
ax1.yaxis.label.set_color('r')
ax1.set_yticks([0,100,200,300,400,500,600,700,800,900,1000])
for label in ax1.xaxis.get_ticklabels():
label.set_rotation(45)
ax1.grid(True, color= 'r', linestyle='-', linewidth=0.5)
plt.subplots_adjust(left = 0.09, bottom =0.18, right= 0.94, top= 0.95, wspace=0.2, hspace=0)
plt.title('stock')
plt.xlabel('dates')
plt.ylabel('price')
plt.legend()
plt.show()
这是我认为阻碍的地方
canvas = FigureCanvasTkAgg(fig, master= root) # A tk.DrawingArea.
canvas.draw()
canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1)
toolbar = NavigationToolbar2Tk(canvas, root)
toolbar.update()
canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1)
graph_data('EBAY')
tk.mainloop()
再次感谢您;)
答案 0 :(得分:1)
从您提供的代码中很难完全理解问题。如果您可以更准确地了解错误/问题的性质或发布完整的代码,则可能会更容易获得帮助。
基本思想是,当您嵌入到tkinter中时,不足以使用matplotlib方法(plt.show)显示图像,但是还需要创建canvas元素并在其上绘制图像。因此,我猜应该修改方法graph_data(stock):
的最后一部分,例如包括matplotlib(代码here)中的方法draw_figure
:
def draw_figure(canvas, figure, loc=(0, 0)):
""" Draw a matplotlib figure onto a Tk canvas
loc: location of top-left corner of figure on canvas in pixels.
Inspired by matplotlib source: lib/matplotlib/backends/backend_tkagg.py
"""
figure_canvas_agg = FigureCanvasAgg(figure)
figure_canvas_agg.draw()
figure_x, figure_y, figure_w, figure_h = figure.bbox.bounds
figure_w, figure_h = int(figure_w), int(figure_h)
photo = tk.PhotoImage(master=canvas, width=figure_w, height=figure_h)
# Position: convert from top-left anchor to center anchor
canvas.create_image(loc[0] + figure_w/2, loc[1] + figure_h/2, image=photo)
# Unfortunately, there's no accessor for the pointer to the native renderer
tkagg.blit(photo, figure_canvas_agg.get_renderer()._renderer, colormode=2)
# Return a handle which contains a reference to the photo object
# which must be kept live or else the picture disappears
return photo
def graph_data(stock, canvas):
# do you really need stock parameter? it is not used
fig = plt.figure()
ax1 = plt.subplot2grid((1,1), (0,0))
url_stock = 'https://pythonprogramming.net/yahoo_finance_replacement'
source_code = urllib.request.urlopen(url_stock).read().decode()
stock_data = []
source_split = source_code.split('\n')
for line in source_split[1:]:
line_split = line.split(',')
if len(line_split) == 7:
if 'values' not in line and 'labels' not in line:
stock_data.append(line)
date, closep, highp, lowp, openp, adj_closep, volume = np.loadtxt(stock_data, delimiter =',', unpack= True, converters={0: bytespdate2num('%Y-%m-%d')})
ax1.plot_date(date, closep, '-', label ='closing price')
ax1.axhline(closep[0], color='k', linewidth = 2)
ax1.fill_between(date, closep, closep[0], where=(closep > closep[0]), facecolor='g', alpha=0.5)
ax1.fill_between(date, closep, closep[0], where=(closep < closep[0]), facecolor ='r', alpha = 0.5)
ax1.xaxis.label.set_color('c')
ax1.yaxis.label.set_color('r')
ax1.set_yticks([0,100,200,300,400,500,600,700,800,900,1000])
for label in ax1.xaxis.get_ticklabels():
label.set_rotation(45)
ax1.grid(True, color= 'r', linestyle='-', linewidth=0.5)
plt.subplots_adjust(left = 0.09, bottom =0.18, right= 0.94, top= 0.95, wspace=0.2, hspace=0)
plt.title('stock')
plt.xlabel('dates')
plt.ylabel('price')
plt.legend()
plt.show()
fig_x, fig_y = 100, 100
fig_photo = draw_figure(canvas, fig, loc=(fig_x, fig_y))
fig_w, fig_h = fig_photo.width(), fig_photo.height()
因此,它仅使用您创建的画布并在其上绘制在matplotlib中绘制的图像。很难确定它是否已经可以像这样工作,或者是否需要进行少量编辑,因为我看不到整个代码,但这应该会给您一个提示。
我可以向您指出完整的文档,其中提供了有关如何在tkinter中嵌入一个图像的简单示例, https://matplotlib.org/gallery/user_interfaces/embedding_in_tk_canvas_sgskip.html 您可以尝试使用它作为测试
或通过使用PIL库转换图像(这是我使用的解决方案),然后将其转换为Tkinter(转换后更直接)的另一种方式https://solarianprogrammer.com/2018/04/20/python-opencv-show-image-tkinter-window/