【问题标题】:matplotlib display only one graph of a set of 10 like a slideshowmatplotlib 只显示一组 10 个图形中的一个,就像幻灯片一样
【发布时间】:2017-01-18 23:10:44
【问题描述】:

我有一组 10 个图表。 (基于 X/Y 对)(本例中只有 3 个) 显示一个图表很容易,在同一个窗口中显示所有图表。(见图)

但我还没有找到我想要的解决方案: 这 10 张图是来自频谱分析仪的数据,显示的是一个信号。

我想显示第一个图表,删除或移除它并在同一窗口中显示第二个图表。

接下来,第二个图形将被删除,第三个应该被看到(依此类推)

这是我的代码:

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()

你有什么想法吗? 我也看过 plt.animate。但我还没有找到符合这些建议的解决方案。

谢谢。 安迪

【问题讨论】:

标签: python matplotlib graph


【解决方案1】:

一个接一个地显示数据对我来说似乎有点不符合人体工程学。同样使用动画可能不是最好的解决方案。如果在检查了第二个数据集后你想回到第一个数据集怎么办?

因此,我将实施一个允许在光谱之间来回切换的解决方案。

以下沙盒示例基于a solution I have provided to a similar problem with images。它使用离散的 Slider 浏览页面。尽管乍一看可能有点复杂,但您不必真正了解 PageSlider 类即可使用它。只需查看__main__ 部分中的代码即可。

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()

上面的代码正在运行并显示了它的外观。在您的特定情况下,您需要对其进行一些更改。 我尝试相应地调整您的代码,但当然我不能保证它有效。此代码必须放在__main__ 部分下方,PageSlider 必须保持不变。

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()


编辑:

对于一个简单的动画,你宁愿使用matplotlib.animation.FuncAnimation 并且代码看起来与这些类似

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()

【讨论】:

  • 感谢您的快速回复。明天我会更深入地了解一下。我想教我们的年轻学生频谱分析仪的工作原理。如果你连续播放 xy 数据,它看起来比静态图片更好。接下来的几天,我将对一个开关盒进行编程,在那里我可以调整一些东西。例如,如果您将 RBW 降低 10 dB,则频谱 (x-y) 也会降低 10 dB。
  • 很抱歉,当我在思考为什么有人会对测量数据进行动画处理时,我想出了这个滑块解决方案。但是知道这是为了模拟测量设备,使用自动动画是有意义的。我在答案中添加了一段代码。
【解决方案2】:

我喜欢建议在 2D 矩阵布局中使用多个子图并为其设置动画。示例(无动画)可以从http://matplotlib.org/examples/pylab_examples/subplots_demo.htmlhttps://www.dataquest.io/blog/images/python_r/python_pairs.png 中看到。

通过这种方式,您的学生可以同时看到所有数据的变化。第一个示例中给出了子图的实现细节。 Furas 已将您引导至情节动画示例。

【讨论】:

    猜你喜欢
    • 2016-01-02
    • 1970-01-01
    • 2011-12-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多