Right approach for speeding up presentation of large amount of data? - python

First question ever on stackoverflow. Been reading for some time now, while trying to learn Python and wxPython.
I'm writing a small app for presenting a large amount of data on the screen in a custom way. The data is stock information stored in objects in Python. Its about 100 stocks that should be presented at the same time on the screen. Every stockobject has 35 attributes, so it makes 3 500 attributes showing at the same time. And I want different fonts, size and colour depending on attribute. The background of each stockobject is changing depending on user (me) input.
So I tried making a interface with wxPython and a lot of StaticText controls. It took 5 seconds to load, timing it with timeit module.
Googling the net gave me an idea to draw the data on a device context instead. That took only 0.1 second. To make the app clickable I draw a second picture into memory with specific colours for each attribute. When clicking on the panel showing the picture I compare the coordinates with the DC in memory to calculating what was clicked. And now I am about to write a sizer routine so the user can change fontsize.
Well my question is quit simple: Do you think I chose the right approach?
Or is there a simpler more pythonic way to do this, without using StaticText that took forever to load?
Grids is not a solution for me, because I want the data to be presented in a very specific layout. To be able to do that with a grid, I would have to set the grid to 2px with and hight, and then merge cells all over the place...
edit:
link for downloading picture of the controll as it looked yesterday:
http://dl.dropbox.com/u/10606669/super.png
Ugly and not the exact way I want it to lok. This because of trying to write my own sizer routine.

You can try freezing the whole frame during the loading process, like this:
frame.Freeze()
try:
# load all data
finally:
frame.Thaw()
In general, though, having that many Window controls will hurt performance, so custom drawing is the only solution. You could simplify things a little by creating your own custom control for one stock (with its own EVT_PAINT handler, etc.) and then creating 100 of them. It should make your DC calculations easier. See Creating Custom Controls for more information.

Related

How can I use python to identify a certain state of a graphic on the screen?

Let me make my question more clear. I am making a program where the program simulates a certain set of keypresses in a video game when a certain 'graphic' fully 'charges' up. This graphic is basically a vertical bar that fills up all the way to the top. How can I use python to interpret this graphic and return some info when the bar is visually fully charged up. The position of the graphic on the screen is always consistent and the state of the bar when it is indeed fully charged up, is always the same.
Probably the easiest way to achieve that is to use the ImageGrab module from Pillow.
And then use some pixels in the snapshot to determine if the bar is filling.
Pillow docs - https://pillow.readthedocs.io/en/3.0.x/reference/ImageGrab.html

Simple animation in Python using wxPython objects

I'm writing a gravity simulator in Python 2.7 and at the moment I finished the mathematical part. I'm trying to find a way to display the results while the simulation is running, it should consist of some colored circles representing the various bodies and optionally some curved lines to represent orbits, that can be shown or hidden while the simulation is running.
I pictured a way to obtain this result, but I can't seem to find a way to even start.
My idea is to use wxPython. The window should be divided into four sectors (2x2), the first three contain the simulation viewed in the XY, XZ and YZ planes, while the last contains the controls (start/stop simulation, show/hide orbits, ...).
The controls should not be a problem, I just need a way to display the animation. So how can I display moving circles and curved lines using wxPython objects? Which objects should I use? I don't need much more than a couple names, the rest should follow easily.
I know that an animation purely with wxPython will probably require some multithreading, I'm already prepared for that. I also want to stress that I need the animation to be shown while the simulation is running, not after, because the simulation has no definite end at the moment: I don't know when to stop it if I don't see the results first.
If it's somehow useful, I'm using Ubuntu Linux 17.10.
Edit: Since I was asked to choose one approach, I discarded Matplotlib because it requires two different windows. Hope this helps.

Simple animations in Python 2.7 [duplicate]

This question already has answers here:
simple animation using tkinter
(2 answers)
Closed 6 years ago.
In Python 2.7, I want to display some simple graphics, such as a red square moving around on a blue window. On every frame, I want to update the position of the square, and render the new window. I am looking for something simple and lightweight.
I have seen people use matplotlib for drawing shapes, but I don't want to have to deal with axes and data points. I have also seen pygame suggested, but this seems to heavyweight for what I want, as I do not want to create a game, just a simple animation.
So what I really want is something where on every frame, I just indicate the colour of every pixel on an image, and then display that image. What are some good suggestions?
Tkinter is not good for setting individual pixels. If you want to move rectangles or ovals though (a small oval will look like a pixel, but it doesn't scale for updating a whole image).
def update(x,y):
canvas.delete('all')
canvas.create_rectangle(x-1,y-1,x+1,y+1)
You can, of course, be more judicious, saving the return value of the rectangle and then only clear the appropriate elements. Or you can move existing elements directly as Bryan points out. As he explains elsewhere Tkinter of course, supports drawing images, ovals, and a slew of other things. Here's a canonical source edit: that is old and not canoncial This one's slightly better For a general source on animating with a timer loop, here's Bryan agian
Bryan also noted that you can work with pixels directly You can do that with PhotoImage.
Array-Like Pixel Access Without Graphical Extensions
A robust module like pygame will be the most scalable option. However, I've had success (in educational settings only) writing graphics engines by modifying the elements of a numpy array and then displaying it as an image (you also need this link to display the images).
This lets you do pixel level modifications; since it's relatively trivial to write C-extensions that modify numpy arrays, you can prototype fast image processing doing custom manipulations. While I've written whole graphics engines using just tkinter this way, again I can only reccomend it for educational purposes.
Otherwise, just bite the bullet and pull in openGl or pygame. You'll save yourself a ton of time in the long run.
Summary
Very simple animations can be done right in tkinter
For educational purposes, you can do arbitrary graphics with numpy and tkinter
For rhobust animations, check out a full library (openGl, matplotlib, pygame) that suits your needs (graphical rendering, statistical graphing, game development, etc.)

wxPython: how to lay one panel over another

This is about wxPython.
I would like to have 2 Panels laying one over the other:
PanelBG should be some sort of a "background", with its own GridBagSizer with subPanels, StaticTexts and so on;
PanelFG should be the "foreground" panel, also with its own GridBagSizer with some StaticTexts, Buttons... but a transparent background, in such a way that PanelBG is visible wherever PanelFG doesn't lay widgets.
I need both Panels to stretch to all the sides of the frame, even when resizing the window, though never changing the reciprocal proportions, that's why I'm not sure if there's a way to use absolute positioning.
In case you are wondering, the reason why I don't want to use a single Panel is that merging the 2 GridBoxSizers would require me to place many many more cells in the sizer, because rows and columns of foreground and background don't always coincide, and I should split them in many cells, with grid dimensions growing up to hundreds**2.
Since the content I want to put in the foreground needs to be updated and refreshed quite often, this would require redrawing all the cells every time, which would take 10 - 20 seconds to complete the operation (tested). Updating only the foreground would require just some hundredths of a second instead.
Thank you!
This would be at least partially a change of direction, but it might be worth examining what other rendering options you have.
In particular, I'm thinking of wxWebKit (http://wxwebkit.kosoftworks.com/), which would let you do layering, etc. using the WebKit browser rendering engine. I'm not sure whether it's at a stage that would provide everything you need since I haven't actually used it, but even if it doesn't work then it may be an approach worth trying - using HTML/CSS for part of your display, while wrapping the whole in a wxPython app.
As I understand it, this is a calendar with rectangles for the days containing the events for the days.
The simple thing would be to use a wxGrid, with seven columns and four or five rows, to represent the months. You would then place the events into the grid cell for the correct date. The wxGrid widget would look after the details of refreshing everything properly.
Using wxGrid you might lose a little control over the exact appearance, though wxGrid is very flexible and feature rich once you learn its many methods, but you would save yourself having to write large amounts of code that would require significant effort to debug.

Creating a Selection tool using PyGtk

Can anyone help or point me in the right direction for figuring out how to create a drag and draw rectangular box to be used as a selection tool in PyGtk? I am presently using an event box with a drawable window and the user can click once in the upper left and once in the lower right corner of the portion of image they would like to choose which will then draw a rectangle over the selection, but a drag and draw rectangle will allow the user to better adjust and get better accuracy.
I have looked quite a few places for information or a tutorial on this but I haven't found much. I am relatively new to Gtk+ so perhaps this is so simple that no one has to ask.
Actually, this doesn't seem all that lamebrained at all. It is actually quite specific, and a little challenging.
I'll give you the steps to start you off, but as you're beginning (and you didn't post any specific code), it would be better for you to create the code yourself based on documentation and my hints.
By the way, look up the official PyGTK documentation - that should be your definitive source for all the objects and functions of PyGTK. It is very well written and exhaustive, and I rarely have to look more than five minutes to find what I need.
What I suggest you do is use three signals, connected to your drawing area.
button-press-event
button-release-event
motion-notify-event
Create three callbacks (tutorial here), one for each event. Connect your drawing area to your events and callbacks (again, see tutorial. You may need to go through a few pages on it.).
You are going to also need to create two boolean variables on the global level (above the main class, at the same level you import modules.) The first controls whether the selection tool is chosen (call it "Select_On"), and the second for if it is active (call it "Select_Active")
On the button you use to start the select tool, set "Select_On" to "True". This should probably be a toggle button, so make sure you set it up so "Select_On" gets set to off if you toggle the button off.
On button-press-event, create the object for selecting. What you're going with now actually should work well. Also, set "Select_Active" to "True".
On motion-notify-event, change the size of your object based on cursor position. Refer to that documentation for that particular kind of object to learn how to change its size, and refer here for how to get the cursor position.
Be prepared to write an algorithm to determine how to change the size of the selection object based on the cursor position. If you need help with that, feel free to ask for it in a separate question.
On button-release-event, set "Select_Active" to "False", and call all your code for actually confirming the selection.
As an aside, the benefit to using the "motion-notify-event" is that, as soon as the cursor leaves the widget you're selection in, the selection box stops changes sizes. The cursor must re-enter the widget to continue changing the selection box size.
I hope all that works for you, and wishing you the very best on your project!

Categories

Resources