The idea would be that you'd have some 2D library for your GUI like PyGame and then draw the plots into the window generated by the library instead of an independent window generated by matplotlib. Allowing for user input and plot viewing in the same window.
I don't have any specific 2D library in mind, I'm not super familiar with Python libraries.
The only way I could find is by saving the plots to a file and then rendering that, but that seems extremely costly for real-time rendering (which is what I'm considering).
You can embed a plot from matplotlib into a tkinter app, check out their documentation here!
https://matplotlib.org/3.1.0/gallery/user_interfaces/embedding_in_tk_sgskip.html
Tkinter is a built-in package with cross platform support.
I am looking for a way to convert a 3D scene from mayavi into a python image format like PIL. I read the documentation but nothing really fits my need. Is it possible to do that in an efficient manner, e.g. a loop over scenes without rendering every one of it first?
Note: You really only need to read the checklist and understand that I want to do this in Tkinter, the rest of the information is for clarification
The complete code is here: https://gist.github.com/SnugBug/1cc5ea67d11487d69aae8549107372ef
I need to be able to manipulate pixels. The goal is to be able to:
Control which pixels are drawn first
Change the color and position of each pixel
Update everything as a whole, so that if a pixel changes the change shows up
Clear everything as a whole
The question is, what's the fastest way to check off this list in tkinter? I tried creating an image with PIL, then loading it into tkinter, but I cannot update the image or clear it. The other thing I tried is using tkinter's PhotoImage class, as shown below:
#The function definitions are in the GIST.
#This snippet should be enough information to understand the problem, however.
for i in range(0,3600):
rot = [0,i,0]
Tx,Ty,Tz,Zm = [0,0,200,200]
x,y,z = [10,10,10]
for m,n in itertools.product(range(-50,50,2),range(-50,50,2)):
x,y,z = rotate([m,n,0],rot)
img.put("#ffffff", (int(WIDTH/2 + ((x+Tx)*Zm/(z+Tz))), int(HEIGHT/2 - ((y+Ty)*Zm/(z+Tz)))))
canvas.update()
img.blank()
#the confusing math in the `img.put` call is just 3D math
This way is extremely slow. The next way I tried is even slower. It's drawing a line like this:
canvas.create_line(x,y,x+1,y+1, ...)
Which creates a line of length 1, showing a single pixel. This is excruciatingly slow.
If the separate image method is the fastest, could you include a working snippet in your answer? I cannot figure out the separate image method. I have PIL installed, that's what I was using to attempt it. I lost the python file so I cannot include the code I used to attempt the separate image method.
What I mean by the separate image method: create an image using PIL, drawing on it using PIL, then making that show up on a tkinter screen. This doesn't meet everything on the checklist, however (from what I understand).
If the separate image method is not the fastest, please tell me a way I can check off everything in the checklist some other way. I have a few questions I looked at for help and some sites. They're below
Why is Photoimage put slow?
Any of these answers don't work for me because it only creates squares. I need to be able to make any shape.
python tkinter: how to work with pixels?
This answer doesn't work because it's too slow.
How to load .bmp file into BitmapImage class Tkinter python This could be helpful
http://zetcode.com/gui/tkinter/drawing/ None of these methods work because I cannot manipulate the order each pixel is drawn, and the color of each individual pixel. If you are familiar with 3D terminology, I need this for a Z-Buffer
If there are any confusions or you need something clarified, please tell me below in the comment section. I am open minded, so if you have a deep understanding of my question and have another idea on how to solve it, I would love to hear it.
If you are using Windows, then the fastest way to put an image on a frame is by ImageWin. The tkinter process of first transforming from PIL image to a tkphotoimage is very slow.
from PIL import Image, ImageWin
from win32gui import GetDC
from tkinter import Tk
root = Tk()
im = Image.open(<file path>)
ImageWin.Dib(im).draw(
GetDC(ImageWin.HWND(root.winfo_id())),
(0,0,100,100)
)
When I use pylab and python under Linux to draw and show an image, like in the following example:
img = pylab.imread(filename)
pylab.imshow(img)
pylab.show()
pylab.draw()
When I do so, a new window pops up with the image.
My question: How can I influence the position and the size?
The whole point of pylab's Image stuff is that you get a np.array of pixel data.
So, you can just do this:
img = pylab.imread(filename)
img = img * myTransformationMatrix
pylab.imshow(img)
If that immediately tells you what you need to know, great. If you don't understand what matrix multiplication has to do with rotating, translating, and scaling images, pylab is probably not the image library you want to use. Just use PIL.
If you're trying to manipulate the windows, rather than the images, pylab is really not meant for that.
You probably want to use TkInter, the windowing library that comes built-in with Python. It's can be ugly, clunky, and slow, and some advanced uses are either impossible or require you to write Tcl code instead of Python… but for simple stuff, it's not going to be a step down from pylab. In fact, it's what pylab uses under the covers.
If you start to hit the limits of TkInter, it's time to look at an external windowing library. You can go with a full GUI framework like Gtk+, Qt, or wx. The Python bindings to the three aren't that different; the important difference is that in the slightly different models of how GUIs work, so read about them and pick the model you like best. Alternatively, you can use something like pygame, which does very bare-bones windowing (the kind of thing games would need, rather than, say, word processors).
I am using a thirdparty library that utilizes a circular buffer for image data and video. It has a method for getting the last image or popping it. I was wondering what would be the best way to implement video functionality in pyqt for this. Is there some video widget with a callback function that I could use? Or do I have to somehow implement parallel processing on my own? Parallel to this, suggestions on how this would be implemented in qt if you dont know how to implement it in pyqt would also be very much appreciated.
Thanks in advance!
I would pop the last image (from the circular buffer) and load it into a QPixmap. This allows you to put the image into a form that a pyqt4 gui would be able to load.
Depending on your libraries image format (straight forward bmp? jpg? png? raw pixels?), you can load the data into the QPixmap in one of two ways.
First: do it pixel by pixel (set the width and height of the image and copy each pixels value over one by one). This method is slow and I'd only resort to it if necessary.
Second: if the image is being stored in a common format (ones that are 'supported' are listed here), this becomes trivial.
Then after the image is loaded in the QPixmap, I would use QLabel.setPixmap() to display the image.
Do this with a QTimer slot at a certain rate and you'll be able to display your images in a pyqt4 gui.