cx_freeze error building PyQT5+Matplotlib Python 3 application - user-interface

I'm having problems compiling an executable for an application I made using:
- Python 3.3
- PyQT5
- Matplotlib
I tried using Cx_Freeze with this setup.py:
import sys
from cx_Freeze import setup, Executable
includes = ['sys','PyQt5.QtCore','PyQt5.QtGui', 'PyQt5.QtWidgets','matplotlib']
excludes = []
packages = []
path = []
base = None
if sys.platform == 'win32':
base = 'Win32GUI'
options = {
'build_exe': {
"includes": includes,
"excludes": excludes,
"packages": packages,
"path": path
#'excludes': ['Tkinter'] # Sometimes a little finetuning is needed
}
}
executables = [Executable('pyqt5_matplotlib.py', base=base)]
setup(name='pyqt5_matplotlib',
version='0.1',
description='Sample PyQT5-matplotlib script',
executables=executables,
options=options
)
When running setup.py build a folder containing various dlls and the exe is created, no error at this time.
When running the exe thus created I get this error:
http://i.stack.imgur.com/D0nsq.jpg
Can anyone please help me?
For the purpose of this question I will include a sample main script that when built reproduces the error:
# #author: Sukhbinder Singh
#
# Simple QTpy and MatplotLib example with Zoom/Pan
#
# Built on the example provided at
# How to embed matplotib in pyqt - for Dummies
#
# http://stackoverflow.com/questions/12459811/how-to-embed-matplotib-in-pyqt-for-dummies
#
# """
import sys
from PyQt5.QtWidgets import (QApplication, QCheckBox, QColorDialog, QDialog,
QErrorMessage, QFileDialog, QFontDialog, QFrame, QGridLayout,
QInputDialog, QLabel, QLineEdit, QMessageBox, QPushButton, QWidget, QVBoxLayout )
from PyQt5.QtCore import pyqtSlot, QDir, Qt
from PyQt5 import QtGui
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt5agg import NavigationToolbar2QTAgg as NavigationToolbar
import matplotlib.pyplot as plt
import numpy
import random
class Window(QDialog):
def __init__(self, parent=None):
super(Window, self).__init__(parent)
self.figure = plt.figure()
self.canvas = FigureCanvas(self.figure)
self.toolbar = NavigationToolbar(self.canvas, self)
#self.toolbar.hide()
# Just some button
self.button = QPushButton('Plot')
self.button.clicked.connect(self.plot)
self.button1 = QPushButton('Zoom')
self.button1.clicked.connect(self.zoom)
self.button2 = QPushButton('Pan')
self.button2.clicked.connect(self.pan)
self.button3 = QPushButton('Home')
self.button3.clicked.connect(self.home)
# set the layout
layout = QVBoxLayout()
layout.addWidget(self.toolbar)
layout.addWidget(self.canvas)
layout.addWidget(self.button)
layout.addWidget(self.button1)
layout.addWidget(self.button2)
layout.addWidget(self.button3)
self.setLayout(layout)
def home(self):
self.toolbar.home()
def zoom(self):
self.toolbar.zoom()
def pan(self):
self.toolbar.pan()
def plot(self):
#''' plot some random stuff '''
#data = [random.random() for i in range(25)]
data_matrix = numpy.random.random((256,256))
ax = self.figure.add_subplot(111)
ax.hold(False)
#ax.plot(data, '*-')
ax.imshow(data_matrix)
self.canvas.draw()
if __name__ == '__main__':
app = QApplication(sys.argv)
main = Window()
main.setWindowTitle('Simple QTpy and MatplotLib example with Zoom/Pan')
main.show()
sys.exit(app.exec_())

After a more in depth research I did the following:
Installed PyWin32
Installed beta release of cx_Freeze (might not be necessary) https://bitbucket.org/anthony_tuininga/cx_freeze/downloads
edited python33/Lib/site-packages/matplotlib/mpl-data/matplotlibrc so that line 32:
backend: tkAgg
becomes
backend: Agg
last source was ImportError: No module named backend_tkagg
This solution works on Win 7 64bit with Python3.3 for a single window PyQT5 with Matplotlib backends.

Related

name 'Path' is not defined

Here you can see the Python-code. As output then always appears: name 'Path' is not defined.
import tkinter as tk
from tkinter import filedialog
from tkinter import *
import pandas as pd
f = open("test_filedialog.txt", "w")
f.close()
def openfile():
Path=filedialog.askopenfilenames(title ="Datein auswählen", filetypes=[("CSV-Datein", "*.csv"),("alle Datein", "*.*")]).open("test_filedialog.txt", "w")
f = open("test_filedialog.txt", "w")
f.write(str(Path))
f.close()
x = tk.Tk()
title= x.title("Titelleiste")
label1=tk.Label(x, text="Hallo", width=25, height=5)
label1.pack()
button1=tk.Button (x, text="Exit",width= 10, height=1, command=x.destroy)
button1.pack()
button2=tk.Button (x, text= "open file", width= 15, height=2, command=openfile)
button2.pack()
x.mainloop()
#import matplotlib import pyplot as plt
daten=pd.read_csv(Path, header=None, sep=';',) #liest jetzt ausgewählte Spalten ein --> Die Frage ist wie wir das für Spaltenbereiche machen
df=daten.drop(range (2),axis=1)
new_header=df.iloc[0]
df=df[1:]
df.columns=new_header
auswahl=df.loc[:,158.936:159.01]
print(auswahl)
if __name__ == "__main__":
root = tkinter.Tk()
app = testApp(root)
root.mainloop()
`
I tried to define the 'Path' as an extra class. But unfortunately this did not lead to any result.
It would be nice if you have a solution for the problem. Maybe how to define the 'Path' as an extra class but also another solution would be ok :)
In python a variable defined inside a function does not have global scope. You shoud define a Path variable that is path to a csv file. You have error at line 38.
import pandas as pd
path = './data.csv' # path to csv file
df = pd.read_csv(path)
print(df.to_string())
Actually I should have tried to run the script.I have not fixed the error.
import tkinter as tk
from tkinter import filedialog
from tkinter import *
import pandas as pd
def read_csv(Path):
daten=pd.read_csv(Path, header=None, sep=',',)
print(daten)
# df=daten.drop(range (2),axis=1)
# new_header=df.iloc[0]
# df=df[1:]
# df.columns=new_header
# auswahl=df.loc[:,158.936:159.01]
# print(auswahl)
def openfile():
Path=filedialog.askopenfilenames(title ="Datein auswählen", filetypes=[("CSV-Datein", "*.csv"),("alle Datein", "*.*")])[0]
read_csv(Path) # do file operation in this function
x = tk.Tk()
title= x.title("Titelleiste")
label1=tk.Label(x, text="Hallo", width=25, height=5)
label1.pack()
button1=tk.Button (x, text="Exit",width= 10, height=1, command=x.destroy)
button1.pack()
button2=tk.Button (x, text= "open file", width= 15, height=2, command=openfile)
button2.pack()
x.mainloop()
#import matplotlib import pyplot as plt
if __name__ == "__main__":
root = tk()
# app = testApp(root)
root.mainloop()
The askopenfile function does not return an object but a tupple with file names. Also you should do file operations in openfile function. Hope it helps.

Is it possible to make the internal dependencies inside a python module user selectable?

After testing the logger library locally, I uploaded it to pypi.
Afterwards, when I proceeded with pip install, there was an error saying that the module inside the library could not be found.
So, as a temporary measure, I added a syntax to register all .py in init.py in the library package folder, and I want to improve this. This is because you have to install all dependencies for features that users may not be using
What improvements can I take in this situation?
If possible, I would like to know how to lazy use only the modules used by the user instead of registering all .py in init.py .
Or is there something structurally I'm overlooking?
Here is the project structure I used
project_name
- pacakge_name
- __init__.py. <- all loggers were registered
- file_logger.py
- console_logger.py
- ...
- fluent_logger.py <- used external library
- scribe_logger.py <- used external library
init.py
"""
Description for Package
"""
from .composite_logger import CompositeLogger
from .console_logger import ConsoleLogger
from .file_logger import FileLogger
from .fluent_logger import FluentLogger
from .jandi_logger import JandiLogger
from .line_logger import LineLogger
from .logger_impl import LoggerImpl
from .logger_interface import LoggerInterface
from .logger import Logger
from .memory_logger import MemoryLogger
from .null_logger import NullLogger
from .scribe_logger import ScribeLogger
from .telegram_logger import TelegramLogger
from .retry import Retry
__all__ = [
'CompositeLogger',
'ConsoleLogger',
'FileLogger',
'FluentLogger',
'JandiLogger',
'LineLogger',
'LoggerImpl',
'LoggerInterface',
'Logger',
'MemoryLogger',
'NullLogger',
'ScribeLogger',
'TelegramLogger',
'Retry',
]
setup.py
import setuptools
from distutils.core import setup
with open("README.md", "r", encoding="utf-8") as f:
long_descriprion = f.read()
setuptools.setup(
name = 'project_name',
version = '0.0.1',
description = 'python logger libary',
long_description = long_descriprion,
long_description_content_type = "text/markdown",
author = 'abc',
author_email = 'abc#gmail.com',
url = "https://github.com/##/##",
packages = ["pacakge_name"],
install_requires=[ <- contains too many external libraries
'requests>=2.0.0',
'thrift>=0.16.0',
'facebook-scribe>=2.0.post1',
'fluent-logger>=0.10.0'
],
keywords = ['logger'],
python_requires = '>=3.7',
classifiers = [
'Programming Language :: Python :: 3.7',
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent"
],
)

Saving or downloading plotly iplot images on Google Colaboratory

I have been attempting to download a plot created using plotly on google colaboratory. So far this is what I have attempted:
I have tried changing
files.download('foo.svg')
to
files.download('foo')
and I still get no results. I navigated to the files on Google colab and nothing shows there
import numpy as np
import pandas as pd
from plotly.offline import iplot
import plotly.graph_objs as go
from google.colab import files
def enable_plotly_in_cell():
import IPython
from plotly.offline import init_notebook_mode
display(IPython.core.display.HTML('''<script src="/static/components/requirejs/require.js"></script>'''))
init_notebook_mode(connected=False)
#this actually shows the plot
enable_plotly_in_cell()
N = 500
x = np.linspace(0, 1, N)
y = np.random.randn(N)
df = pd.DataFrame({'x': x, 'y': y})
df.head()
data = [
go.Scatter(
x=df['x'], # assign x as the dataframe column 'x'
y=df['y']
)
]
iplot(data,image = 'svg', filename = 'foo')
files.download('foo.svg')
This is the error I am getting:
OSErrorTraceback (most recent call last)
<ipython-input-18-31523eb02a59> in <module>()
29 iplot(data,image = 'svg', filename = 'foo')
30
---> 31 files.download('foo.svg')
32
/usr/local/lib/python2.7/dist-packages/google/colab/files.pyc in download(filename)
140 msg = 'Cannot find file: {}'.format(filename)
141 if _six.PY2:
--> 142 raise OSError(msg)
143 else:
144 raise FileNotFoundError(msg) # pylint: disable=undefined-variable
OSError: Cannot find file: foo.svg
To save vector or raster images (e.g. SVGs or PNGs) from Plotly figures you need to have Kaleido (preferred) or Orca (legacy) installed, which is actually possible using the following commands in Colab:
Kaleido:
!pip install kaleido
Orca:
!pip install plotly>=4.0.0
!wget https://github.com/plotly/orca/releases/download/v1.2.1/orca-1.2.1-x86_64.AppImage -O /usr/local/bin/orca
!chmod +x /usr/local/bin/orca
!apt-get install xvfb libgtk2.0-0 libgconf-2-4
Once either of the above is done you can use the following code to make, show and export a figure (using plotly version 4):
import plotly.graph_objects as go
fig = go.Figure( go.Scatter(x=[1,2,3], y=[1,3,2] ) )
fig.show()
fig.write_image("image.svg")
fig.write_image("image.png")
The files can then be downloaded with:
from google.colab import files
files.download('image.svg')
files.download('image.png')
Try this, it does work for me:
import plotly.graph_objects as go
fig = go.Figure(...) # plot your fig
go.Figure.write_html(fig,"file.html") # write as html or image
files.download("file.html") # download your file and give me a vote my answer

Set break points in Tornado app

How could I set a break point in my tornado app?
I tried pdb, but Tornado app seams to be ignoring my pdb.set_trace() command in my app.
If you are running your app using foreman you would set you environment variable in .env file in root project folder.
Setting the below env variable in my .env file did the tick form me.
PYTHONUNBUFFERED=true
Now I can set code breakpoints in my app, and also print output to server logs while running the app using foreman.
Where did you put pdb.set_trace()...? This works for me:
#!/usr/bin/python
# -*- coding: utf-8 -*-
import tornado.httpserver
import tornado.ioloop
import tornado.options
import tornado.web
import pdb
from tornado.options import define, options
define("port", default=8000, help="run on the given port", type=int)
class IndexHandler(tornado.web.RequestHandler):
def get(self):
greeting = self.get_argument('greeting', 'Hello')
reself.write(greeting + ', friendly user!')
if __name__ == "__main__":
tornado.options.parse_command_line()
app = tornado.web.Application(handlers=[(r"/", IndexHandler)])
http_server = tornado.httpserver.HTTPServer(app)
http_server.listen(options.port)
pdb.set_trace()
tornado.ioloop.IOLoop.instance().start()
Session:
$ python test.py
> /home/mariusz/Dokumenty/Projekty/Testy/test.py(24)<module>()
-> tornado.ioloop.IOLoop.instance().start()
(Pdb) break 16
Breakpoint 1 at /home/mariusz/Dokumenty/Projekty/Testy/test.py:16
(Pdb) continue
> /home/mariusz/Dokumenty/Projekty/Testy/test.py(16)get()
-> self.write(greeting + ', friendly user!')
(Pdb) step
--Call--
> /usr/local/lib/python2.7/dist-packages/tornado/web.py(497)write()
-> def write(self, chunk):
(Pdb) step
> /usr/local/lib/python2.7/dist-packages/tornado/web.py(512)write()
-> if self._finished:
(Pdb) step
> /usr/local/lib/python2.7/dist-packages/tornado/web.py(516)write()
-> if isinstance(chunk, dict):
(Pdb)
After putting continue in above code debugger stopped, because I had to poll http://localhost:8000/ in browser to have RequestHandler function actually called.

GAE + Python2.7 + webapp2 + AJAX

Are there any tutorials or code examples related to AJAX implementation for GAE + Python2.7 + webapp2.
I have tried to follow instructions below:
http://code.google.com/appengine/articles/rpc.html
but I receive the following error:
Traceback (most recent call last):
File "E:\dev\workspace\test\webapp2.py", line 1536, in __call__
rv = self.handle_exception(request, response, e)
File "E:\dev\workspace\test\webapp2.py", line 1530, in __call__
rv = self.router.dispatch(request, response)
File "E:\dev\workspace\test\webapp2.py", line 1278, in default_dispatcher
return route.handler_adapter(request, response)
File "E:\dev\workspace\test\webapp2.py", line 1101, in __call__
handler = self.handler(request, response)
TypeError: __init__() takes exactly 1 argument (3 given)
There is another similar discussion here:
Google App Engine Python Protorpc Error: __call__() takes exactly 1 argument (3 given)
heres is my code from Specialscope's example:
main.py
from BaseHandler import BaseHandler
from google.appengine.ext import blobstore
from google.appengine.ext.webapp import blobstore_handlers
import logging
from google.appengine.api import files
from google.appengine.api import images
import json
import webapp2
class FileuploadHandler(BaseHandler):
def get(self):
blobstore.create_upload_url('/static')
context={}
self.render_response("uploader.html",**context)
class FileDownloadHandler(blobstore_handlers.BlobstoreUploadHandler,BaseHandler):
def post(self):
upload_files=self.request.POST
#image=upload_files['file']
logging.error(upload_files)
keys=upload_files.keys()
imageurls=[]
for key in keys:
if key.find("uploadimage")!=-1:
image=upload_files[key]
file_name=files.blobstore.create(mime_type='image/jpg')
with files.open(file_name,'a') as f:
f.write(image.value)
files.finalize(file_name)
blob_key=files.blobstore.get_blob_key(file_name)
imageurls.append(images.get_serving_url(blob_key))
context={}
context['imagelinks']=imageurls
self.response.write(json.dumps(context))
app = webapp2.WSGIApplication([
('/upload', FileuploadHandler),
('/download', FileDownloadHandler),
], debug = True)
BaseHandler.py
import webapp2
import os
from webapp2_extras import jinja2
from google.appengine.ext import db
class BaseHandler(webapp2.RequestHandler):
#webapp2.cached_property
def jinja2(self):
# Returns a Jinja2 renderer cached in the app registry.
return jinja2.get_jinja2(app=self.app)
def render_response(self, _template, **context):
# Renders a template and writes the result to the response.
rv = self.jinja2.render_template(_template, **context)
self.response.write(rv)
The stack trace suggests that you have a url mapping in your WSGIApplication that has a group in it, but there's no handler with the corresponding arguments.
If you have
(r'/foo/(\s+)/(\s+)', FooHandler),
then you need
class FooHandler(webapp2.RequestHandler):
def get(self, arg1, arg2):
...
The doc you're using pre-dates Python 2.7 support by several years. Were I in your position, I'd be tempted to get the app working first on Python 2.5, then port to 2.7.
The problem is here:
import webapp2
app = webapp2.WSGIApplication([
('/upload', FileuploadHandler),
('/download', FileDownloadHandler),
], debug = True)
You can't use webapp2.WSGIApplication to construct your application, it doesn't understand protorpc. Instead, do this:
from protorpc.wsgi import service
app = service.service_mappings([
('/upload', FileuploadHandler),
('/download', FileDownloadHandler),
])

Resources