jarvisteach / appJar

Simple Tkinter GUIs in Python
http://appJar.info
Other
615 stars 68 forks source link

How to use matplotlib(metpy) to display data created in the background #535

Closed vbdyron closed 5 years ago

vbdyron commented 6 years ago

Context


Hi there, I am new to python coding (and Github) and have been studying it for the last month and a half. I have been trying to implement what I learned that is directly in relation to my field of work/expertise (weather). I have created a script that can do some data retrieval. The input for this data retrieval goes through appJar. Internally I can manipulate the data to create a figure which can be viewed in the console output. However, I cant seem to figure out how to display it in the appJar interface using matplotlib. I did read on the website that the matplotlib widget is intended to create some simple graphs. But I was hoping that I could just create it in the background and let the widget just do the display work in the SKEW T tab. Is it possible to do what I want in appJar or should I wait for a future release? I have attached a PDF and RST(just to make copy pasting easier) that shows the libraries that I am using, the code used to build the appJar interface and the ouput.

Sample code, demonstrating the issue


Sounding Retrieval Utility(pre skew output).pdf

Sounding Retrieval Utility(pre skew output).zip

Version Information


appJar 0.93.0 matplotlib 2.2.2 py36_1 conda-forge metpy 0.8.0 py36_0 conda-forge numpy 1.15.0 py36_blas_openblash8d851b4_200 [blas_openblas] conda-forge numpy-base 1.14.3 py36h5c71026_0

jarvisteach commented 6 years ago

There are a lot of dependencies there, that I don't have installed, and a lot of code to try to work my way through...

I think what you're asking, is: "is there a way to run a process in the background, which generates data, and then updates a plot in appJar"

If so, then the answer is yes.

Have a look here: http://appjar.info/pythonThreads/

You can write a function that generates all the data you want, run it in a thread, and have it use the update queue to modify your GUI..

jarvisteach commented 6 years ago

Here's an example:

from appJar import gui 
from numpy import sin, pi, arange
import random, time

def getXY():
    x = arange(0.0, 3.0, 0.01)
    y = sin(random.randint(1,app.slider('yVal') +1) * pi * x)
    return x,y 

def generate():
    while True:
        app.queueFunction(app.updatePlot, 'p1', *getXY())
        time.sleep(1)

with gui() as app:
    app.label('MatPlotLib Demo')
    app.slider('yVal', show=True, pos=[2,0])
    app.addPlot("p1", *getXY(), row=1)

    app.thread(generate)
vbdyron commented 6 years ago

Thank You Jarvis, This is interesting, you got general idea of what I wanted to do, I'll try this out and give you the feedback on my attempt. The way I managed to solve it on my end (while waiting for your input), was to generate the PNG image file and then display it with Canvas. It is a bit limiting solution, but it did get the job done.

JaredMGoldman commented 5 years ago

I was wondering if you could include any more advanced labeling techniques in a graph displayed on a gui (i.e. multiple plots with different colors and a legend). These features are available on a matplotlib.pyplot graph and I was wondering if there would be any way to directly instantiate a pyplot graph into the gui. My initial ideas are by creating a new widget type that displays the image of a pyplot graph, as seen from the show() method in pyplot or display a .png as mentioned above.

The latter solution is not ideal and I would like to use this ability to display a live graph within the gui that updates as data is received from an outside source. I could use your built-in software, but I may need to display up to 9 graphs, so I would prefer to compress the data into two graphs (one with up to 8 subplots) which I could easily accomplish with a pyplot graph.

Any help is greatly appreciated!