датчик matplotlib обновляется динамически

Я попытался создать такой датчик в matplotlib:

http://www.highcharts.com/demo/gauge-solid

Это почти работает. Это код на данный момент:

    import numpy as np
    import matplotlib.pyplot as plt
    import matplotlib.animation as animation
    from matplotlib.patches import Wedge
    from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as                 FigureCanvas

    from matplotlib.figure import Figure
    import sys,os
    from PyQt4 import QtGui,QtCore

    class MyMplCanvas(FigureCanvas):
        """Ultimately, this is a QWidget (as well as a FigureCanvasAgg, etc.)."""
        def __init__(self, parent=None):
            self.fig = Figure(facecolor='#DBE0E4')
            self.axes = self.fig.add_subplot(111,axisbg='#DBE0E4')
            self.axes.axis('off')
            #here I create the contour of the gauge
            #the two horizontal lines
            x1=[-1,-0.6]
            x2=[0.6,1.0]
            y=[0.004,0.004]
            self.axes.plot(x1,y,color='#646464')
            self.axes.plot(x2,y,color='#646464')
            #and the 2 circles(inner and outer)
            circle1=plt.Circle((0,0),radius=1,fill=False)
            circle1.set_edgecolor('#646464')
            circle1.set_facecolor(None)

            circle2=plt.Circle((0,0),radius=0.6,fill=False)
            circle2.set_edgecolor('#646464')
            circle2.set_facecolor(None)
            self.axes.add_patch(circle1)
            self.axes.add_patch(circle2)

            #Scaling of the figure
            self.axes.axis('scaled')
            self.axes.set_xlim(-1.1,1.1)
            self.axes.set_ylim(0,1.1)

            FigureCanvas.__init__(self, self.fig)
            self.setParent(parent)

            FigureCanvas.updateGeometry(self)


    class Gauge(MyMplCanvas):
        def __init__(self,meter,parent=None):
            MyMplCanvas.__init__(self)


            self.patches=[]
            #here I create the wedge to start
            self.wedge=Wedge((0,0),0.99,1,179,width=0.38,facecolor='#FF0000')
            self.patches.append(self.wedge)
            self.timeClear=0
            self.update_figure()
            #self.Online_meter=meter
            #here starts the update
            timer=QtCore.QTimer(self)
            timer.timeout.connect(self.update_figure)
            timer.start(5000)

        def update_figure(self):
            #here is the update command
            #every 5 sec, I call value from a measurement instrument
            #here I let the program generate random values
            self.timeClear=self.timeClear+1
            #new_data=self.Online_meter.__call__()
            self.wedge.set_theta1(180-np.random.random(1)*10/10*179)
            self.axes.add_patch(self.wedge)    
            self.draw()

До сих пор это работает. Код написан с целью добавить это как виджет в программу PyQt 4. У них осталась только одна проблема: когда значение обновляется, датчик меняется внезапно, но я хотел бы видеть, что датчик обновляется (поэтому я хочу видеть, что угол клина меняется, так медленно движется). Надеюсь, вы, ребята, сможете Помоги мне. Или, может быть, это уже хорошая библиотека для вставки красивых датчиков в графический интерфейс pyqt4?

Спасибо, что помогли мне заранее!


person Driedan    schedule 03.03.2015    source источник
comment
Здесь много кода. Многие люди готовы помочь вам понять, что происходит, но не хотят разбираться в таком большом (возможно, не связанном) коде. Большинство вопросов, связанных с mpl, можно задать с помощью ‹20 строк кода. Если SO дает вам полосу прокрутки, вы вставили слишком много кода.   -  person tacaswell    schedule 04.03.2015
comment
Решил уже сам. В любом случае спасибо за совет. Однако сделать этот код короче непросто, потому что задействованы две библиотеки (Pyqt4 и matplotlib), которые должны работать вместе. Итак, чтобы прояснить эту проблему, было необходимо, чтобы код был немного длинным. Я попытался сделать его читабельным, добавив больше комментариев в код ..   -  person Driedan    schedule 05.03.2015
comment
Тогда ответьте на свой вопрос.   -  person tacaswell    schedule 05.03.2015
comment
Я выложил ответ. Я надеюсь, что вы сможете дать обратную связь для объяснения и ответа.   -  person Driedan    schedule 05.03.2015


Ответы (1)


Я сам решил. В приведенном выше коде программа сама генерирует число от 0 до 10 (в методе update_figure). Предположим, число четыре.

Это значит, что на клин:

    theta1 = 180-number/10*179  
    #as always theta2:
    theta2 =180 

через 5 секунд программа сгенерирует другое число (например: 6.5)

это означает, что свойства клина должны измениться.

Добавив цикл for в метод update_figure объекта Gauge:

    def update_figure(self):

            self.timeClear=self.timeClear+1
            #the old value becomes temp
            temp=self.new_data
            self.number=np.random.random(1)*10
            self.new_data=180-self.number/10*179

            step=(self.new_data-temp)/10
            for x in range(10):

                self.wedge.set_theta1(temp+step*x)
                self.axes.add_patch(self.wedge)    
                time.sleep(1/10)
                self.draw()

Взяв разницу между старым числом и новым числом и разделив ее на 10. Вы можете легко менять датчик динамически и медленно, добавляя этот цикл for и позволяя клину рисовать себя 10 раз (при этом theta1 изменяется за 10 шагов от старый номер на новый) со временем ожидания 100 мс. Если это объяснение непонятно, спросите меня, и я попытаюсь объяснить его еще раз.

person Driedan    schedule 05.03.2015
comment
Вам не нужно добавлять клин каждый раз через петлю. - person tacaswell; 10.03.2015
comment
@tcaswell Извините за поздний ответ, но я не могу найти решение, не добавляя клин каждый раз. (Это замедляет работу программы) Интересно, знаете ли вы решение? - person Driedan; 13.04.2015
comment
Вам нужно добавить его только один раз. - person tacaswell; 13.04.2015
comment
Я не понимаю, как это сработало для вас. Так много ошибок. Как вы назвали этот виджет? Как вы начали? - person Tal Kohavy; 21.03.2020