wxPython can't properly position a matplotlib block - python-2.7

I've taken the code to draw a rectangle over image form here, and modified it a little bit to suite my purposes. The only problem I have, it doesn't appear to be full screen, even though I make fr.ShowFullScreen(True). There is a grey area around the image.
Edited code is below (the rectangle part is not relevant):
# Use the wxPython backend of matplotlib
import matplotlib
matplotlib.use('WXAgg')
# Matplotlib elements used to draw the bounding rectangle
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas
from matplotlib.figure import Figure
# wxPython stuff for the demo
import wx
class RectangleSelectImagePanel(wx.Panel):
def __init__(self, parent, pathToImage=None):
# Initialise the parent
wx.Panel.__init__(self, parent)
# Intitialise the matplotlib figure
self.figure = Figure(figsize=(20,15), dpi=80)
# Create an axes, turn off the labels and add them to the figure
self.axes = self.figure.add_subplot(1, 1, 1)
self.axes.set_axis_off()
# Add the figure to the wxFigureCanvas
self.canvas = FigureCanvas(self, -1, self.figure)
# Sizer to contain the canvas
self.sizer = wx.BoxSizer(wx.VERTICAL)
self.sizer.Add(self.canvas, 0, wx.ALL)
self.SetSizer(self.sizer)
self.Fit()
def setImage(self, pathToImage):
'''Sets the background image of the canvas'''
import matplotlib.image as mpimg
# Load the image into matplotlib
image = matplotlib.image.imread(pathToImage)
# left in as anchor for image size
self.imageSize = image.shape[0:2]
print self.imageSize
#
# Add the image to the figure and redraw the canvas. Also ensure the aspect ratio of the image is retained.
self.axes.imshow(image, interpolation="quadric", aspect='auto')
self.canvas.draw()
if __name__ == "__main__":
# Create an demo application
app = wx.App()
# Create a frame and a RectangleSelectorPanel
fr = wx.Frame(None, title='test')
panel = RectangleSelectImagePanel(fr)
# Set the image in the panel
from matplotlib.cbook import get_sample_data
imgpath = get_sample_data('logo2.png', asfileobj=False)
panel.setImage(imgpath)
# Start the demo app
fr.ShowFullScreen(True)
app.MainLoop()

probably what you need is subplots_adjust.
from pylab import *
from matplotlib.cbook import get_sample_data
imgpath = get_sample_data('logo2.png', asfileobj=False)
image = matplotlib.image.imread(imgpath)
imshow(image, aspect='auto')
subplots_adjust(left=0, right=1, top=1, bottom=0, wspace=0, hspace=0)
This will produce a plot that has no margin around the image.
So, if you put
self.figure.subplots_adjust(left=0, right=1, top=1, bottom=0, wspace=0, hspace=0)
after imshow line, you will get something closer to what you need.
Then, you will probably have to adjust the figsize parameter too. for my 1920 x 1080 display, I will need 1920.0/80 inch by 1080.0/80 inch so (24,13.5)

Related

Python executable hangs with plt.show()

I am creating a GUI application (EXE) in Python 2.7 on Win 10 platform.
The application is supposed to plot a graph (using matplotlib) with user provided parameters. When the user changes the values and presses the plot button again, new graph should be plotted on the same figure retaining the previous curves for ease of comparison (also a requirement).
I had to use plt.show() at the end of the script to show the graph when running the exe file of my program.
Problem: Application freezes and crashes when the plot button is pressed the second time. For the first time, everything goes fine and the graph is displayed.
Solutions tried:
Going thru so many threads, I tried following solutions without luck:
Used plt.draw() instead of plt.show() because the later blocks program execution. But draw() does not display the graphs.
Tried plt.pause(), the application gives RunTime error and crashes.
Also played with ion() / ioff().
Tried plt.show(block = False), the application crashes on second click on plot button.
I came across various backends that can be used with matplotlib and suspected that plt.show() might work well with other backends. Tried TkAgg, WxAgg, and others but no luck.
I would really appreciate if someone can help me with this...already tried for 3 days!!
Code sample:
from PyQt4 import QtCore, QtGui
import numpy as np
import matplotlib
matplotlib.use('TkAgg') #Trying different backends
import matplotlib.pyplot as plt
plt.rc('xtick', labelsize = 16)
plt.rc('ytick', labelsize = 16)
import FileDialog #These three imports needed for EXE
import tkFileDialog
import tkMessageBox
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
#UI elements code...
def retranslateUi(self, MainWindow):
#Other code lines
def my_Plot_Function():
#Some calculations
plt.figure('My title')
plt.plot(x, y, label = 'My Label')
plt.grid(True)
plt.axhline(y = 0, color = 'k')
plt.xlabel(' X ', fontsize = 16)
plt.ylabel(' Y ', fontsize = 16)
plt.legend(prop={'size': 14})
plt.show()
if __name__ == "__main__":
import sys
app = QtGui.QApplication(sys.argv)
MainWindow = QtGui.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())

Radio Buttons won't select jpg

Shortened the code to minimum for the question. I want to toggle between images to apply on the canvas using radiobuttons. The code will only apply the images if I enter the image name, (ex. tkimg2) into the 'stamp' event. The radiobuttons are not selecting the images, nor does the link work if I enter the image name in picture=[]. Do you know why the image name is sufficient in one location and not the other and why the radiobuttons don't work? Thank you for any help
from Tkinter import *
import PIL
from PIL import ImageTk, Image
import random
import os.path
root = Tk()
shapes = []
#load 2 images for stamping
__dir__ = os.path.dirname(os.path.abspath(__file__))
filename = os.path.join(__dir__, 'balloon.jpg')
img = PIL.Image.open(filename)
tkimg=PIL.ImageTk.PhotoImage(img)
filename2 = os.path.join(__dir__, 'bird1.jpg')
img2 = PIL.Image.open(filename2)
tkimg2=PIL.ImageTk.PhotoImage(img2)
picture =[]
image=picture
# A Radiobutton to toggle between images
radio = [0]*2
v = IntVar()
def call():
if int(float(str(v.get())))==1:
picture=tkimg
else:
picture=tkimg2
Label(root, text ="Select an image to place.").grid(row=1, column=0,
columnspan=5, sticky=S)
R1=Radiobutton(root, text="Bird 1", variable=v, value=1, command=call)
R1.grid(row=2, column=0, sticky=N+E)
R1.select()
R2=Radiobutton(root, text="Bird 2", variable=v, value=2, command=call)
R2.grid(row=2, column=1, sticky=N+E)
# A canvas for mouse events and image drawing
canvas = Canvas(root, height=1000, width=1000, bg='#2EEAFF')
canvas.grid(column=5, row=0, rowspan=4, sticky=W)
# Bind a function to the left mouse button down event.
def stamp(event):
canvas.create_image(event.x,event.y,image)
canvas.bind('<ButtonPress-1>', stamp)
# Enter event loop
root.mainloop()
I removed most of the code not relevant to the question and changed the images to ordinary PhotoImages for simplicity. Also I changed the first positioning of the image on the canvas.
If you want to assign a value to a variable inside a function you'll have to make it global or it will not work. The variable will be defined in the local function scope and will be garbage collected when the function ends.
I don't think you can change an image on a canvas by updating the variable you used to create it. That's how a StringVar functions.
As the image is the only widget on the canvas I delete ALL items and then create a new image when I toggle images.
Also: I use Python 3.6 so I spell tkinter without the capital T.
from tkinter import *
root = Tk()
#load 2 images for stamping
tkimg = PhotoImage(file='test.gif') # Test image
tkimg2 = PhotoImage(file='tesu.gif') # Test image
# A Radiobutton to toggle between images
v = IntVar()
def call():
canvas.delete(ALL)
if v.get() == 1:
canvas.create_image((2, 2), image=tkimg, anchor=NW)
else:
canvas.create_image((2, 2), image=tkimg2, anchor=NW)
Label(root, text ="Select an image to place.").grid(row=1, column=0, columnspan=5, sticky=S)
R1=Radiobutton(root, text="Bird 1", variable=v, value=1, command=call)
R1.grid(row=2, column=0, sticky=N+E)
R1.select()
R2=Radiobutton(root, text="Bird 2", variable=v, value=2, command=call)
R2.grid(row=2, column=1, sticky=N+E)
# A canvas for mouse events and image drawing
canvas = Canvas(root, height=200, width=200, bg='#2EEAFF')
canvas.grid(column=5, row=0, rowspan=4, sticky=W)
canvas.create_image((2, 2), image=tkimg, anchor=NW)
# Enter event loop
root.mainloop()

Thumbnailctrl size (trying to get it to fullscreen)

I've been trying to insert two Thubmnailctrl under a Multisplitter, I have managed to put them in there, but I can't manage to make them ocuppy the full space. On thumbnailctrl.py I've seen that on the the maximum size it can be is 350x280:
def SetThumbSize(self, width, height, border=6):
"""
Sets the thumbnail size as width, height and border.
:param `width`: the desired thumbnail width;
:param `height`: the desired thumbnail height;
:param `border`: the spacing between thumbnails.
"""
if width > 350 or height > 280:
return
self._tWidth = width
self._tHeight = height
self._tBorder = border
self.SetScrollRate((self._tWidth + self._tBorder)/4,
(self._tHeight + self._tBorder)/4)
self.SetSizeHints(self._tWidth + self._tBorder*2 + 16,
self._tHeight + self._tBorder*2 + 8)
But on the other hand on the demo under ThumbnailCtrl, it uses an Splitter to create a Thumbnailctrl as big as you want, so I don't know if I'm doing something wrong (maybe with Sizers) or is some feature from Splitter (totally diferent than multisplitter) that allows the Thumbnailctrl to occupy it's full space.
Thumbnailctrl + Splitter Demo:
import wx
import os
import sys
try:
dirName = os.path.dirname(os.path.abspath(__file__))
except:
dirName = os.path.dirname(os.path.abspath(sys.argv[0]))
sys.path.append(os.path.split(dirName)[0])
try:
from agw import thumbnailctrl as TC
except ImportError: # if it's not there locally, try the wxPython lib.
import wx.lib.agw.thumbnailctrl as TC
class MainFrame(wx.Frame):
def __init__(self, redirect=False, filename=None):
wx.Frame.__init__(self, None, title="Elephant")
# self.SetMenuBar(self.CreateMenuBar())
splitter = wx.SplitterWindow(self, -1, style=wx.CLIP_CHILDREN | wx.SP_3D | wx.WANTS_CHARS | wx.SP_LIVE_UPDATE)
self.panel = wx.Panel(splitter, -1)
sizer = wx.BoxSizer(wx.HORIZONTAL)
scroll = TC.ThumbnailCtrl(splitter, -1, imagehandler=TC.NativeImageHandler)
scroll.ShowFileNames()
if os.path.isdir("../bitmaps"):
scroll.ShowDir(os.path.normpath(os.getcwd() + "/../bitmaps"))
else:
scroll.ShowDir(os.getcwd())
self.TC = scroll
splitter.SplitVertically(scroll, self.panel, 180)
splitter.SetMinimumPaneSize(140)
self.SetMinSize((700, 590))
self.CenterOnScreen()
if __name__ == "__main__":
app = wx.App(False)
frame = MainFrame()
# import wx.lib.inspection
# wx.lib.inspection.InspectionTool().Show()
app.MainLoop()
My attempt at a Multisplitter with two thumbnails (and when that works a third panel with text and stuff):
import wx
import os
import cv2
import ctypes
from PIL import Image
from wx.lib.splitter import MultiSplitterWindow
try:
from agw import thumbnailctrl as TC
except ImportError: # if it's not there locally, try the wxPython lib.
import wx.lib.agw.thumbnailctrl as TC
class SamplePane(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent)
self.thumbnail11 = TC.ThumbnailCtrl(self, imagehandler=TC.NativeImageHandler, thumboutline=4)
self.thumbnail11.EnableDragging(True)
# self.thumbnail11.SetThumbSize(350, screensize[0] / 15, 25) # For images -> Max values 350,280
# ################VID################ #
topmostSizer = wx.BoxSizer(wx.VERTICAL)
topmostSizer.Add(self.thumbnail11, proportion=0, flag=wx.EXPAND)
self.SetSizer(topmostSizer)
self.MaxSize
# topmostSizer.Fit(self)
class MainFrame(wx.Frame):
""""""
def __init__(self):
"""Constructor"""
wx.Frame.__init__(self, None, title="Elephant")
splitter = MultiSplitterWindow(self, style=wx.SP_LIVE_UPDATE)
# t1Sizer = wx.BoxSizer(wx.VERTICAL)
# self.thumbnail11 = TC.ThumbnailCtrl(splitter, imagehandler=TC.NativeImageHandler, thumboutline=4)
panel = SamplePane(splitter)
splitter.AppendWindow(panel)
panel2 = SamplePane(splitter)
splitter.AppendWindow(panel2)
# t1Sizer.Add(panel, proportion=0, flag=wx.EXPAND)
self.Show()
if __name__ == "__main__":
app = wx.App(False)
frame = MainFrame()
# import wx.lib.inspection
# wx.lib.inspection.InspectionTool().Show()
app.MainLoop()
As you can see there are two thumbnails and they expand left to right, but they are capped at a maximum height.
Thanks a lot for the help!
Not 100% sure what it is that you're trying achieve with this but I suspect that your problem is with the topmostSizer's proportion attribute.
Try:
topmostSizer.Add(self.thumbnail11, proportion=1, flag=wx.EXPAND)
From the manual:
proportion - Although the meaning of this parameter is undefined in
wx.Sizer, it is used in wx.BoxSizer to indicate if a child of a sizer
can change its size in the main orientation of the wx.BoxSizer - where
0 stands for not changeable and a value of more than zero is
interpreted relative (a proportion of the total) to the value of other
children of the same wx.BoxSizer.
In this case, you have defined topmostSizer as VERTICAL

opencv face detection CAPTCHA

please im working on using face detection as a captcha system. how do i make the system print an error message if a face is not detected in the webcam. and also make the number of attempts to detect a face is 3 such that after 3 attempts it closes in python
from Tkinter import *
import numpy as np
import cv2
import Tkinter as tk
import tkMessageBox
import random
import webbrowser
def Request_1(event):
#messagebox gestures
trials = 0
while trials<3:
tkMessageBox.showinfo("ATTENTION!!!", "press letter a when you see the yellow box on your nose")
#this aspect is to generate random requests for the captcha system
detector2= cv2.CascadeClassifier('haarcascade_mcs_nose.xml')
cap = cv2.VideoCapture(0)
access = True
while(access):
#reads the image
ret2, img2 = cap.read()
gray2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
# Detect faces in the image . the image is read and convertedd to grayscale
faces2 = detector2.detectMultiScale(gray2, 1.3, 5)
if(len(faces2)!=0):
for (x,y,w,h) in faces2:
cv2.rectangle(img2,(x,y),(x+w,y+h),(0,255,255),1)
cv2.imshow('frame',img2)
break
if cv2.waitKey(1) & 0xFF == ord('a'):
#grant access to webpage
cap.release()
cv2.destroyAllWindows()
new=2
url="file:///C:/Users/jayrush/Desktop/lmarku/index.html";
webbrowser.open(url, new=new);
break
if(len(faces2)==0):
trials=trials+1
print("Access Denied")
#defining the interface of the captcha
#INTERFACE
root = Tk()
root.title("Face Detection CAPTCHA")
root.geometry("350x50")
bottomFrame = Frame(root)
bottomFrame.pack()
button_1 = Button(bottomFrame, fg="blue", text="I am not a robot")
button_1.bind("<Button-1>", Request_1)
button_1.pack()
status = Label(root, fg="red", text="Starting captcha...", bd=1, relief=SUNKEN, anchor=W)
status.pack(side=BOTTOM, fill=X)
root.mainloop()

how to display a form within a frame using python and tkinter

I have created a notebook(file1.py) using python and tkinter. This notebook has three tabs A,B,C. I have another python file(file2.py) which contains few text fields. Now I am looking for a way to display the contents of the other file2.py within the tab A which is in file1.py.The following is the code I used in file1.py
import tkinter as tk
import tkinter.ttk as ttk
root = tk.Tk()
# use width x height + x_offset + y_offset (no spaces!)
root.geometry("%dx%d+%d+%d" % (300, 200, 100, 50))
root.title('test the ttk.Notebook')
nb = ttk.Notebook(root)
nb.pack(fill='both', expand='yes')
# create a child frame for each page
f1 = tk.Frame(bg='red')
f2 = tk.Frame(bg='blue')
f3 = tk.Frame(bg='green')
# create the pages
nb.add(f1, text='A')
nb.add(f2, text='B')
nb.add(f3, text='C')
# put a button widget on child frame f1 on page1
btn1 = tk.Button(f1, text='button1')
btn1.pack(side='left', anchor='nw', padx=3, pady=5)
root.mainloop()
File2.py
import sys
from PyQt4 import Qt
from taurus.qt.qtgui.application import TaurusApplication
app = TaurusApplication(sys.argv)
panel = Qt.QWidget()
layout = Qt.QHBoxLayout()
panel.setLayout(layout)
from taurus.qt.qtgui.panel import TaurusForm
panel = TaurusForm()
model = [ 'test/i1/1/%s' % p for p in props ]
panel.setModel(model)
panel.show()
sys.exit(app.exec_())
I am new to using tkinter and python so could you let me know how I could achieve it. Also in the other file(file2.py) I have few import statements like 'import sys" etc.Thanks.
You cannot mix those two files. One uses Tkinter, one uses PyQT. Those two libraries are incompatible with each other.