2

I have a set of 10 graphs. (based on X/Y-pairs) (In this example only 3)all 10 graphs together Displaying one graph is easy, same to all graphs in the same window.(See picture)

But I haven't found a solution for what I want : The 10 graphs are Data from a spectrum analyzer and are showing a signal.

I want to display the first graph, delete or remove it and display the 2nd graph in the same window.

Then next, the second graph will be removed and the 3rd shall be seen (and so on)

Thats my Code :

from matplotlib import pyplot as plt
import numpy as np

datei = ['./2450ATT0.csv','./2450ATT0-1.csv','./2450ATT0-2.csv']

for file in datei:
    x = np.genfromtxt(file, usecols =(0), delimiter=';', unpack=True)
    y = np.genfromtxt(file, usecols =(1), delimiter=';', unpack=True, dtype=float)

    plt.xlim(2435,2465)
    plt.ylim(-120,-20)
    plt.xlabel('Frequenz')
    plt.ylabel('Leistung')
    plt.plot(x/1000000,y, label=file)  
plt.show()

Do you have any idea ? I also have had a look at plt.animate. but I haven't found a solution with that suggestions.

Thank you. Andi

  • `matplot` has `FuncAnimation` ie. http://matplotlib.org/examples/animation/simple_anim.html – furas Jan 18 '17 at 23:40

2 Answers2

3

Showing the data one after the other seems a bit unergonomic to me. Also using an animation might not be the best solution. What if after inspection of the second dataset you want to go back to the first?

I would therefore implement a solution which allows to go back and forth between the spectra.

The following sandbox example is based on a solution I have provided to a similar problem with images. It uses a discrete Slider to walk through the pages. Although it may seem a bit complicated on first sight, you do not really have to understand the PageSlider class in order to use it. Just look at the code down in the __main__ part.

import matplotlib.widgets
import matplotlib.patches
import mpl_toolkits.axes_grid1

class PageSlider(matplotlib.widgets.Slider):

    def __init__(self, ax, label, numpages = 10, valinit=0, valfmt='%1d', 
                 closedmin=True, closedmax=True,  
                 dragging=True, **kwargs):

        self.facecolor=kwargs.get('facecolor',"w")
        self.activecolor = kwargs.pop('activecolor',"b")
        self.fontsize = kwargs.pop('fontsize', 10)
        self.numpages = numpages

        super(PageSlider, self).__init__(ax, label, 0, numpages, 
                            valinit=valinit, valfmt=valfmt, **kwargs)

        self.poly.set_visible(False)
        self.vline.set_visible(False)
        self.pageRects = []
        for i in range(numpages):
            facecolor = self.activecolor if i==valinit else self.facecolor
            r  = matplotlib.patches.Rectangle((float(i)/numpages, 0), 1./numpages, 1, 
                                transform=ax.transAxes, facecolor=facecolor)
            ax.add_artist(r)
            self.pageRects.append(r)
            ax.text(float(i)/numpages+0.5/numpages, 0.5, str(i+1),  
                    ha="center", va="center", transform=ax.transAxes,
                    fontsize=self.fontsize)
        self.valtext.set_visible(False)

        divider = mpl_toolkits.axes_grid1.make_axes_locatable(ax)
        bax = divider.append_axes("right", size="5%", pad=0.05)
        fax = divider.append_axes("right", size="5%", pad=0.05)
        self.button_back = matplotlib.widgets.Button(bax, label=ur'$\u25C0$', 
                        color=self.facecolor, hovercolor=self.activecolor)
        self.button_forward = matplotlib.widgets.Button(fax, label=ur'$\u25B6$', 
                        color=self.facecolor, hovercolor=self.activecolor)
        self.button_back.label.set_fontsize(self.fontsize)
        self.button_forward.label.set_fontsize(self.fontsize)
        self.button_back.on_clicked(self.backward)
        self.button_forward.on_clicked(self.forward)

    def _update(self, event):
        super(PageSlider, self)._update(event)
        i = int(self.val)
        if i >=self.valmax:
            return
        self._colorize(i)

    def _colorize(self, i):
        for j in range(self.numpages):
            self.pageRects[j].set_facecolor(self.facecolor)
        self.pageRects[i].set_facecolor(self.activecolor)

    def forward(self, event):
        current_i = int(self.val)
        i = current_i+1
        if (i < self.valmin) or (i >= self.valmax):
            return
        self.set_val(i)
        self._colorize(i)

    def backward(self, event):
        current_i = int(self.val)
        i = current_i-1
        if (i < self.valmin) or (i >= self.valmax):
            return
        self.set_val(i)
        self._colorize(i)


if __name__ == "__main__":
    import numpy as np
    from matplotlib import pyplot as plt


    num_pages = 10
    data = np.random.rand(700, num_pages)
    spec = np.linspace(-10,10, 700)

    fig, ax = plt.subplots()
    fig.subplots_adjust(bottom=0.18)
    ax.set_ylim([0.,1.6])
    line, = ax.plot(spec,data[:,0], color="b")

    ax_slider = fig.add_axes([0.1, 0.05, 0.8, 0.04])
    slider = PageSlider(ax_slider, 'Page', num_pages, activecolor="orange")

    def update(val):
        i = int(slider.val)
        line.set_ydata(data[:,i])

    slider.on_changed(update)

    plt.show()

enter image description here

The code above is working and shows how this would look like. In your specific case, you would need to change it a bit. I tried to adapt your code accordingly, but of course I cannot guarantee that it works. This code has to be put below the __main__ part, the PageSlider must stay unchanged.

import numpy as np
from matplotlib import pyplot as plt


dateien = ['./2450ATT0.csv','./2450ATT0-1.csv','./2450ATT0-2.csv']
data_x = []
data_y = []
for datei in dateien: #do not call a variable "file" in python as this is protected
    x = np.genfromtxt(datei, usecols =(0), delimiter=';', unpack=True)
    x = x/1000000.
    y = np.genfromtxt(datei, usecols =(1), delimiter=';', unpack=True, dtype=float)
    data_x.append(x)
    data_y.append(y)


fig, ax = plt.subplots()
fig.subplots_adjust(bottom=0.18)
ax.set_xlim([2435,2465])
ax.set_xlim([-120,20])
ax.set_xlabel('Frequenz')
ax.set_ylabel('Leistung')

text = ax.text(0.98,0.98, dateien[0], ha="right", va="top")
line, = ax.plot(data_x[0],data_y[0], color="b")

ax_slider = fig.add_axes([0.1, 0.05, 0.8, 0.04])
slider = PageSlider(ax_slider, 'Page', len(dateien), activecolor="orange")

def update(val):
    i = int(slider.val)
    line.set_data(data_x[i],data_y[i])
    text.set_text(dateien[i])

slider.on_changed(update)

plt.show()


Edit:

For a simple animation, you would rather use matplotlib.animation.FuncAnimation and the code would look something along those lines

import numpy as np
from matplotlib import pyplot as plt

dateien = ['./2450ATT0.csv','./2450ATT0-1.csv','./2450ATT0-2.csv']
data_x = []
data_y = []
for datei in dateien: # do not call a variable "file" in python, this is a protected word
    x = np.genfromtxt(datei, usecols =(0), delimiter=';', unpack=True)
    x = x/1000000.
    y = np.genfromtxt(datei, usecols =(1), delimiter=';', unpack=True, dtype=float)
    data_x.append(x)
    data_y.append(y)


fig, ax = plt.subplots()
fig.subplots_adjust(bottom=0.18)
ax.set_xlim([2435,2465])
ax.set_xlim([-120,20])
ax.set_xlabel('Frequenz')
ax.set_ylabel('Leistung')

line, = ax.plot(data_x[0],data_y[0], color="b")

def update(i):
    line.set_data(data_x[i],data_y[i])

ani = matplotlib.animation.FuncAnimation(fig, update, 
            frames= len(dateien), interval = 200, blit = False, repeat= True)

plt.show()
Community
  • 1
  • 1
ImportanceOfBeingErnest
  • 321,279
  • 53
  • 665
  • 712
  • Thank you for your fast reply. I will have a deeper look tomorrow. I want to teach our young students how a spectrum analyzer works. If you play the xy-data continously, it looks better than a static picture. the next days I will programm a switchbox, where I can adjust a few things. For example if you set down the RBW by 10 dB the spektrum (x-y) also goes down by 10 dB. – Andreas Weise Jan 19 '17 at 00:53
  • I'm sorry, as I was thinking about why someone would animate measurement data, I came up with this slider solution. But knowing that this is rather for simulation of a measurement device, it makes sense to use an automatic animation. I added a piece of code to my answer which does that. – ImportanceOfBeingErnest Jan 19 '17 at 08:40
0

I like to suggest using multiple subplots in a 2D matrix layout and animating them. Examples (w/o animation) can be seen from http://matplotlib.org/examples/pylab_examples/subplots_demo.html and https://www.dataquest.io/blog/images/python_r/python_pairs.png.

In this way your students get to see changes in all the data simultaneously. The implementation details for the subplots are given in the 1st example. Furas has directed you to the plot animation example.

Sun Bear
  • 7,594
  • 11
  • 56
  • 102