0

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)))
Thankk
  • 5
  • 2
  • Have you looked at any tutorials? I am pretty sure that there are quite a few examples of `matplotlib` graphs in `tkinter` windows on the internet. – TheLizzard May 14 '21 at 17:31
  • I have. The problem is almost all of them use Pandas, which I don't and it gets a bit confusing. – Thankk May 14 '21 at 17:33
  • Plus many of them go about creating a def or a class for the graph from scratch. What I want to do is rather kind of create a root that will be inheriting the graph from the commands I already used (I'm not even sure if that's possible in the first place). – Thankk May 14 '21 at 17:41
  • I'm afraid I don't think it does. It's like the ones I saw in the other tutorials, creating seperate defs and classes. Thanks for your help anyway. – Thankk May 14 '21 at 17:46
  • Create a `tkinter` window then use `canvas = FigureCanvasTkAgg(fig, master=root)`. After that you can call `canvas.get_tk_widget().pack()` and `canvas.draw()` to display it in the tkinter window – TheLizzard May 14 '21 at 17:47
  • Thanks. I'll give it a shot. – Thankk May 14 '21 at 17:54
  • Well I just don't get it. It keeps giving me this: canvas = FigureCanvasTkAgg(fig, master=root) NameError: name 'root' is not defined – Thankk May 14 '21 at 18:01
  • Did you create a `tkinter` window first? I assumed that you would name it `root`. – TheLizzard May 14 '21 at 18:05
  • Never mind. I got it! Thanks a lot buddy! I appreciate your help so much! – Thankk May 14 '21 at 18:12

1 Answers1

0

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()

TheLizzard
  • 7,248
  • 2
  • 11
  • 31