Page 1 of 2 12 LastLast
Results 1 to 10 of 16

Thread: Embedding a matplotlib graph in a Tkinter window

  1. #1
    Join Date
    Mar 2005
    Location
    Isle of Bute, Scotland
    Beans
    369
    Distro
    Ubuntu Gnome 14.04 Trusty Tahr

    Embedding a matplotlib graph in a Tkinter window

    I have python 2.7.3 installed on my 12.04 64 bit system. I have written the following:
    Code:
    #!/usr/bin/env python 
    import  numpy as np
    from  matplotlib import  pyplot as plt
    import time
    import sys
    
    
    if len(sys.argv) < 2:
        sys.stderr.write("\n\n\nUsage: " + sys.argv[0] + " needs to know how many points to display\n\n           .. Like this: " + sys.argv[0]  + " 50\n\n\n")
        sys.exit(1)
    howmany = int(sys.argv[1])
    top = 100
    plt.ion () # set plot to animated
    xdata = []
    c = 0
    for a in range(0,top):
        xdata.append(a)
        c+=1
    ydata =  [ 0 ] *  top * 10
    ax1 = plt.axes ()  
    c = 0
    myfile = open("rdata.txt", "r")
    for myline in myfile:
        q = myline
        ydata[c] = q 
        c+=1
    c = 0
    # Make plot
    line, =  plt.plot (ydata[0:howmany])
    
    
    myfile = open("rdata.txt", "r")
    
    
    for p in range(0, top * 10):
    #for myline in myfile:
    #    q = int(myline)
    #    ydata.append (q)
            del  ydata [ 0 ]
            line.set_xdata (np.arange ( len (ydata)))
            line.set_ydata (ydata)   # update the data
    #          time.sleep(0.01)
            plt.draw () # update the plot    
    
    
    #    c +=1
    
    
    
    
    file.close(myfile)
    It reads data from a file I generated using random data.

    Ultimately I want to use it with a micropython board ( a kickstarter project which has python on a microcontroller ) to make a simple form of oscilloscope.
    The code above displays a dynamic graph which looks just like an oscilloscope display but obviously I want to do more.
    As you will see if you run it, the display is constantly updated until it has read all the data then ends.
    What I want to do is get it embedded so the wrapper includes entry, button and other widgets so I can customise the graph from a GUI rather than pass command line parameters. Everything I have found after hours of searching works fine IF you just want a static display.
    For example I tried to modify the following to embed it:
    Code:
    #!/usr/bin/env python
    import matplotlib, sys
    matplotlib.use('TkAgg')
    from numpy import arange, sin, pi
    from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
    from matplotlib.figure import Figure
    from Tkinter import *
    from functools import partial as pto
    
    
    master = Tk()
    master.title("Hello World!")
    #-------------------------------------------------------------------------------
    f = Figure(figsize=(5,4), dpi=100)
    a = f.add_subplot(111)
    t = arange(0.0,3.0,0.01)
    s = sin(2*pi*t)
    a.plot(t, s)
    
    
    dataPlot = FigureCanvasTkAgg(f, master=master)
    dataPlot.show()
    dataPlot.get_tk_widget().pack(side=TOP, fill=BOTH, expand=1)
    #-------------------------------------------------------------------------------
    
    
    master.mainloop()
    But I cannot find out how I can get it to set s to a value in the ydata[] array.
    I have tried, for example:
    Code:
    
    f = Figure(figsize=(5,4), dpi=100)
    a = f.add_subplot(111)
    t = arange(0.0,3.0,0.01)
    for x in range(0,50):
        s = ydata[x]
        a.plot(t, s)
    and many other ideas but I get all sorts of different errors and if, by some chance some of it works, the plot window detaches from the main window and just displays some static plot.
    Any ideas please?
    I won't be able to answer this soon if you have any questions until tonight though.
    Running 14.04 on my HP Pavilion g6 4 Gig Ram 320 Gig Disc

  2. #2
    Join Date
    Nov 2009
    Beans
    3,336

    Re: Embedding a matplotlib graph in a Tkinter window

    Maybe you could pick something out of this example

    http://www.physics.utoronto.ca/~phy3...Plot_Simple.py

    I did a small video to show it working ...... but its the best I could do with my limited knowledge of python and tk

    maybe someone else can help - but saw there was no response to this for 5 days now .....

    http://youtu.be/tYKM-BK-nGQ

    Also stackoverflow.com is a good place for this type of question

    I had to uninstall and rebuild matplotlib to get things working .... so maybe that might help
    also loaded in tk-dev ...... before doing the rebuild .....
    ( hope something here gives you a chance to move it on a little further )

    http://stackoverflow.com/questions/1...ith-underscore
    Last edited by 23dornot23d; January 26th, 2014 at 08:44 AM. Reason: stackoverflow ..... had previously said stackplot .....

  3. #3
    Join Date
    Mar 2005
    Location
    Isle of Bute, Scotland
    Beans
    369
    Distro
    Ubuntu Gnome 14.04 Trusty Tahr

    Re: Embedding a matplotlib graph in a Tkinter window

    Thanks for the reply I had just about given up and was thinking I would stick to the command line.
    I tried copying and pasting the code you suggested but on running it unmodified I got some errors.

    I too am a beginner with tk/tkinter although I do know a fraction more python but I needed to change every instance of

    Code:
    ticks.append(clock())
    to
    Code:
    ticks.append(time.clock())
    I seem to have the same problem with this code as the others I have tried. It's still a matplotlib window and not embedded in, for example, a cell in a grid. Also, as it states it slows down as the number of points increases. If you try the code I have posted you will find this does not happen because only a fixed number of points are displayed although of course these are different as at each iteration the first one has been removed and a new one tacked on at the end.
    Running 14.04 on my HP Pavilion g6 4 Gig Ram 320 Gig Disc

  4. #4
    Join Date
    Nov 2009
    Beans
    3,336

    Re: Embedding a matplotlib graph in a Tkinter window

    I have loaded quite a lot of things in for Python and run version 2.7.3 not sure if it makes a big difference which is run

    but here is a small listing of the main things that I have loaded up ....... as I did not need to change anything in that

    script to get it to work ............ so maybe either some packages are missing or something else to do with the version

    of Python may be causing problems ........

    This link is to where I am messing around with Python for a blackboard program I am trying to make - but its a bit of a

    hack together .......... but the last page has most of my setup files on it ......... and some more information as to how I

    went about setting things up using ....... https://sites.google.com/site/python...up-page-python

    pip install filename.py --upgrade

    might be that numpy or matplotlib need updating ..... there is a script to run that finds the updated packages too .......

    Will add a link to it .........

    Not sure how we can tell which files might be missing ....... but I will try to find a way to get a better listing from my

    setup - but its constantly changing .........

  5. #5
    Join Date
    Mar 2005
    Location
    Isle of Bute, Scotland
    Beans
    369
    Distro
    Ubuntu Gnome 14.04 Trusty Tahr

    Re: Embedding a matplotlib graph in a Tkinter window

    I hunted around for hours after your first post and finally found some code which would do mostly what I want.
    I still cannot embed the matplotlib window in a grid and had already given up using pack()
    I get a window in which I can enter how many points to display in the matplotlib window. When I click on the 'Draw Graph' window a matplot lib window appears somewhere else on the screen. When the whoe number of points has been displayed this new window closes. It's okay but it isn't entirely what I want and doesn't look right as an application.
    I will play around with this some more but here is what I have so far:

    Code:
    #!/usr/bin/env python
    import Tkinter
    from tkSimpleDialog import *
    import math
    import string
    from  matplotlib import  pyplot as plt
    import  numpy as np
    
    def callback():
        sys.exit() 
    
    def plotit():
    #    if (Entry.get(x) < "1"):
    #       text.text = "value must be more then zero"
    #        plt.close()
    
        howmany = int(Entry.get(x))
        top = 100
        plt.ion () # set plot to animated
        xdata = []
        c = 0
        for a in range(0,top):
            xdata.append(a)
            c+=1
        ydata =  [ 0 ] *  top * 10
        ax1 = plt.axes ()  
        c = 0
        myfile = open("rdata.txt", "r")
        for myline in myfile:
            q = myline
            ydata[c] = q 
            c+=1
        c = 0
    # Make plot
        line, =  plt.plot (ydata[0:howmany])
    
        myfile = open("rdata.txt", "r")
        for p in range(0, top * 10):
            del  ydata [ 0 ]
            line.set_xdata (np.arange ( len (ydata)))
            line.set_ydata (ydata)   # update the data
            plt.draw () # update the plot    
        file.close(myfile)
        plt.close()
    
    
    root = Tkinter.Tk()
     
    x = Entry(root)
    x.grid(row=1, column=0, columnspan=2)
    text = Label(root, text="Enter the number of points to display below")
    text.grid(row=0, column=0)
    button1 = Button(text="Exit", command=callback).grid(row=2, column=2, sticky=SE)
    Button(root, text='Plot', command=plotit).grid(row=2, column=3, columnspan=1)
     
    root.mainloop()

    and I used the following to generate the random data:
    Code:
    
    
    #!/usr/bin/env python
    from random import randint
    myfile = open("rdata.txt", "w")
    for p in range(0, 1000):
        q = str(randint(4,90)) + "\n"
        myfile.write(q)
    
    myfile.close()

    If you choose a small number of points, around 50 to 150 to display then it looks quite good.

    I still need to figure out a few bits like error checking on the input into the Entry box.
    I also want to do extra bits relating to selecting a range out of the total number of points out of the total available.
    Running 14.04 on my HP Pavilion g6 4 Gig Ram 320 Gig Disc

  6. #6
    Join Date
    Nov 2009
    Beans
    3,336

    Re: Embedding a matplotlib graph in a Tkinter window

    I added a few debugging print statements to see what was happening ..... here is what I have so far



    The data file that was created from your script is here to

    Download this for the data I used
    https://sites.google.com/site/python...edirects=0&d=1

    The file is just called u1.py
    Download file here https://sites.google.com/site/python...edirects=0&d=1
    Last edited by 23dornot23d; January 27th, 2014 at 01:16 PM.

  7. #7
    Join Date
    Nov 2009
    Beans
    3,336

    Re: Embedding a matplotlib graph in a Tkinter window

    I think that this is the best example and description I have found so far that meets the criteria required here ......

    http://www.lebsanft.org/?p=48

    but all my own efforts so far to reproduce a fully dynamic running example have failed

    ( I have gone from Ubuntu to Debian ) the results are much the same - often no graph or one that shows for a instant and is gone ..........

    I used a older system = ubuntu 12.04 where it appears to start to work and that is the example I showed above in the screenshot



    Just adding to this - one thing that gives me confidence in this being used for real time recording and display
    in this blog - if you watch the video ..... real time sound recording with a graph connected to the input which is
    a microphone ( or in his case a speaker used as a microphone ) .....
    http://www.swharden.com/blog/2013-05...n-with-python/

    Hope something here helps ....

    __________________________________________________ __________________________

    Still not given in on this - as it interests me to see how a live feed could be shown in a graph ......
    but using the methods shown so far - it will probably be a very slow one as explained in the link above .......
    Last edited by 23dornot23d; January 30th, 2014 at 11:40 PM. Reason: Version 12.04 .... just checked.

  8. #8
    Join Date
    Mar 2005
    Location
    Isle of Bute, Scotland
    Beans
    369
    Distro
    Ubuntu Gnome 14.04 Trusty Tahr

    Re: Embedding a matplotlib graph in a Tkinter window

    Well I have been looking more closely at matplotlib widgets and came across some example code. I decided to port the part of my code into one of these and now I only need the matplotlib window. So far I have added 2 of my own buttons and a slider which do what I want more or less so I here is that code:
    Code:
    #!/usr/bin/env python
    import numpy as np
    import matplotlib.pyplot as plt
    from matplotlib.widgets import Button, Slider
    import sys
    
    
    freqs = np.arange(2, 20, 3)
    
    
    fig, ax = plt.subplots()
    plt.subplots_adjust(bottom=0.20, top= 0.90)
    plt.ion
    axcolor = 'lightgoldenrodyellow'
    
    
    def endit(mock):  # mock isn't used it's only there cos an error was reported that the function wasn't expecting a parameter and so failed.
        sys.exit() 
    
    def update(val):
        howmany = int(axvals.val)
    
    
    def plotit(dummy):  # dummy isn't used it's only there cos an error was reported that the function wasn't expecting a parameter and so failed.
        howmany = int(axvals.val)  #int(Entry.get(x))
        top = 100
        plt.ion () # set plot to animated
        xdata = []
        c = 0
        for a in range(0,top):
            xdata.append(a)
            c+=1
        ydata =  [ 0 ] *  top * 10
        ax1 = plt.axes ()  
        c = 0
        myfile = open("rdata.txt", "r")
        for myline in myfile:
            q = myline
            ydata[c] = q 
            c+=1
        c = 0
    # Make plot
        line, =  plt.plot (ydata[0:howmany])
        myfile = open("rdata.txt", "r")
    
    
        for p in range(0, top * 10):
            del  ydata [ 0 ]
            line.set_xdata (np.arange ( len (ydata)))
            line.set_ydata (ydata)   # update the data
            plt.draw () # update the plot    
        file.close(myfile)
    #    plt.close()
    
    
    #callback = plotit()
    axvals = plt.axes([0.15, 0.075, 0.45, 0.03], axisbg=axcolor)
    #axamp  = plt.axes([0.25, 0.15, 0.65, 0.03], axisbg=axcolor)
    
    
    axout = plt.axes([0.81, 0.05, 0.1, 0.075])
    aout = Button(axout, 'Exit')
    aout.on_clicked(endit)
    axplot = plt.axes([0.7, 0.05, 0.1, 0.075])
    aplot = Button(axplot, 'Plot')
    aplot.on_clicked(plotit)
    axvals = Slider(axvals, 'Points\nto plot', 10, 800)
    
    
    plt.show()
    It uses the same data file as before and I want to do more with it. I need to figure out how to position the window displayed on the screen and how to set it's size to what I want. Then i intend to add perhaps 2 Entry Boxes so i can thel it which data point in the file to start at and which one to end at.
    Although I may decide to do more with it.
    To a real programmer this code is probably very crude so if your looking at it by all means suggest inprovements.
    I hope this helps you.
    Running 14.04 on my HP Pavilion g6 4 Gig Ram 320 Gig Disc

  9. #9
    Join Date
    Nov 2009
    Beans
    3,336

    Re: Embedding a matplotlib graph in a Tkinter window

    Sorted - but all to do with a pause ........ after the draw ......

    Download the file here to check it out ..........

    https://sites.google.com/site/python...edirects=0&d=1
    same data file
    https://sites.google.com/site/python...edirects=0&d=1

    Will post a video of it running shortly ....... just in case this does not work the same on all systems.

    No idea why the quality is not good in the video ..... but at least it shows its working ok now

    http://youtu.be/f7UmMLHWPYs
    Last edited by 23dornot23d; January 31st, 2014 at 11:29 PM. Reason: added video showing it working

  10. #10
    Join Date
    Mar 2005
    Location
    Isle of Bute, Scotland
    Beans
    369
    Distro
    Ubuntu Gnome 14.04 Trusty Tahr

    Re: Embedding a matplotlib graph in a Tkinter window

    I got rid of the print statements and saw this:

    /usr/lib/pymodules/python2.7/matplotlib/backend_bases.py:2280: MatplotlibDeprecationWarning: Using default event loop until function specific to this GUI is implemented warnings.warn(str, mplDeprecation)
    I find your changes interesting but I have developed my own code further in line with what I eventually want it to do.
    For example I found out how to get the window full screen:
    changed
    Code:
    fig, ax = plt.subplots()
    to

    Code:
    fig, ax = plt.subplots(figsize=(17, 10))
    17 is the width and 10 the height of the window.
    Running 14.04 on my HP Pavilion g6 4 Gig Ram 320 Gig Disc

Page 1 of 2 12 LastLast

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •