首页 > 解决方案 > How to place a matplotlib plot inside a tkinter window in the simplest way possible?

问题描述

I'm working on a project for university and I have the following code, which pretty much does the job. However, it would be nice if I could take it a step further and put the generated graphs in a tkinter window. I'd love to hear your thoughts if you have any ideas. Thank you in advance for any help.

 import numpy as np
from numpy import random as rd
import matplotlib.cm as cm
import matplotlib.pyplot as plt
#-----------------------------------------------------------------------------------------------------------------------
# Ingredients A & B needed for product 1
A1 = 3
B1 = 8
Shell1 = 100

# Ingredients A & B needed for product 2
A2 = 6
B2 = 4
Shell2 = 125

# Total Capacity of units A & B
CA = 30
CB = 44

# Maximum Production Capacity of 1 & 2
C1 = 5
C2 = 4
#-----------------------------------------------------------------------------------------------------------------------
# Define Optimization Functions
def objective(X,Y):
    return Shell1*X+Shell2*Y

def constrain1(X,Y):
    return CA-A1*X-A2*Y

def constrain2(X,Y):
    return CB-B1*X-B2*Y

def constrain3(X,Y):
    return C1-X

def constrain4(X,Y):
    return C2-Y
#-----------------------------------------------------------------------------------------------------------------------
maxx = int(min(CA/A1,CB/B1))
maxy = int(min(CA/A2,CB/B2))

x = np.linspace(0, maxx+1, maxx+2)
y = np.linspace(0, maxy+1, maxy+2)
X, Y = np.meshgrid(x, y)

# Generate Contour Plot
fig, ax = plt.subplots()
cpm = ax.contourf(objective(X,Y), 10, alpha=.35, cmap = cm.turbo)
cpl = ax.contour(objective(X,Y), 10, colors='black', linewidths=0.2)
cbar = plt.colorbar(cpm)
cbar.set_label('Objective Function Contour Plot', rotation=270, labelpad=20, fontsize=14)
#-----------------------------------------------------------------------------------------------------------------------
# Identify Constrains
c1 = ax.contour(constrain1(X,Y),[0],colors='red', linewidths=3)
c2 = ax.contour(constrain2(X,Y),[0],colors='red', linewidths=3)
c3 = ax.contour(constrain3(X,Y),[0],colors='red', linewidths=3)
c4 = ax.contour(constrain4(X,Y),[0],colors='red', linewidths=3)
ax.clabel(c1, fmt='Constrain 1', manual=[(1,4)], fontsize=9)
ax.clabel(c2, fmt='Constrain 2', manual=[(3,5)], fontsize=9)
ax.clabel(c3, fmt='Constrain 3', manual=[(5,5)], fontsize=9)
ax.clabel(c4, fmt='Constrain 4', manual=[(4.3,4)], fontsize=9)
#-----------------------------------------------------------------------------------------------------------------------
# Potential Feasible Solution
rx = int((rd.rand()) * 5)
ry = int((rd.rand()) * 5)

while constrain1(rx,ry)<0 or constrain2(rx,ry)<0 or constrain3(rx,ry)<0 or constrain4(rx,ry)<0:
    rx = int((rd.rand()) * 5)
    ry = int((rd.rand()) * 5)
    continue

ax.plot(rx,ry,marker='X',color='goldenrod',ms=8,label='Potential FS')
ax.contour(objective(X,Y),[objective(rx,ry)],colors='k', linewidths=2)
#-----------------------------------------------------------------------------------------------------------------------
# Maximum & Minimum Feasible Solution
MAX = MIN = objective(rx,ry)
imax = imin = rx
jmax = jmin = ry

for i in x:
    for j in y:
        if constrain1(i,j)>=0 and constrain2(i,j)>=0 and constrain3(i,j)>=0 and constrain4(i,j)>=0:
            # All Feasible Solutions
            ax.plot(i,j,marker='+',color='k',ms=10)
            if objective(i,j)>MAX:
                MAX = objective(i,j)
                imax = int(i)
                jmax = int(j)
            if objective(i,j)<MIN:
                MIN = objective(i,j)
                imin = int(i)
                jmin = int(j)

ax.plot(imax,jmax,marker='s',color='dodgerblue',ms=8,label='Max Objective FS')
ax.plot(imin,jmin,marker='s',color='deeppink',ms=8,label='Min Objective FS')
#-----------------------------------------------------------------------------------------------------------------------
# Activate Grid
grid = ax.grid(linestyle='dashed')

# Plot Labels
plt.xlabel('Units of Product 1',fontsize=12)
plt.ylabel('Units of Product 2',fontsize=12)
plt.legend(bbox_to_anchor=(0., 1.02, 1, 0), loc='lower left', ncol=2, mode="expand", borderaxespad=0)
plt.show()
#-----------------------------------------------------------------------------------------------------------------------
# Print Results
print('\n' + '\033[35m' + 'Potential Feasible Solution: ' + '\033[0m' + str(rx) + '\033[34m' + ' Units of Product 1, '
      + '\033[0m' + str(ry) + '\033[31m' + ' Units of Product 2: ' + '\033[33m' + 'Revenue = ' + '\033[0m'
      + str(objective(rx,ry)))
print('\n' + '\033[35m' + 'Maximum Feasible Solution: ' + '\033[0m' + str(imax) + '\033[34m' + ' Units of Product 1, '
      + '\033[0m' + str(jmax) + '\033[31m' + ' Units of Product 2: ' + '\033[33m' + 'Revenue = ' + '\033[0m'
      + str(objective(imax,jmax)))
print('\n' + '\033[35m' + 'Minimum Feasible Solution: ' + '\033[0m' + str(imin) + '\033[34m' + ' Units of Product 1, '
      + '\033[0m' + str(jmin) + '\033[31m' + ' Units of Product 2: ' + '\033[33m' + 'Revenue = ' + '\033[0m'
      + str(objective(imin,jmin)))

标签: pythonmatplotlibtkinter

解决方案


Try this:

from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
import tkinter as tk

# All of your code

root = tk.Tk() # Create the tkinter window

canvas = FigureCanvasTkAgg(fig, master=root) # Convert the Figure to a tkinter widget
canvas.get_tk_widget().pack() # Show the widget on the screen
canvas.draw() # Draw the graph on the canvas?

root.mainloop() # Start tkinter's mainloop

That will show your Figure on the screen. Please note that it uses the fig that you defined when you used fig, ax = plt.subplots()


推荐阅读