2

I tried to create a Gauge like this in matplotlib:

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

It almost works. This is the code so far:

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

Until now this works. The code is written for the purpose to add this as a widget in a PyQt 4 program. Their is only one problem left: when the value is updated, the gauge changes suddenly but i'd like to see that the gauge updates( so i want to see the angle of the wedge changing, so slow moving) I hope you guys can help me. Or maybe their is already a good library for inserting good looking gauges in a pyqt4 GUI?

Thanks for helping me in advance !

Driedan
  • 255
  • 1
  • 5
  • 12
  • 1
    Way to much code here. I many people are willing to help you understand what is going on, but are not willing to wade through that much (probably un-related) code. Most mpl related questions can be asked with < 20 lines of code. If SO gives you a scroll bar you have pasted too much code. – tacaswell Mar 04 '15 at 03:11
  • 1
    I solved it already myself. Thanks anyway for the advice. However it's not easy to make this code shorter because there are two libraries involved(Pyqt4 and matplotlib) which have to work together. So for the purpose to make this problem clear it was necessary that is code is bit long. I tried to make it readable by putting more comments into the code.. – Driedan Mar 05 '15 at 11:09
  • 1
    Please answer your own question then. – tacaswell Mar 05 '15 at 14:03
  • 1
    I posted the answer. I hope you can give feedback for the explanation and the answer. – Driedan Mar 05 '15 at 18:17

1 Answers1

1

I solved it myself. In the code above the program itself generates a number between 0-10( in the update_figure method ). Supose the number is four.

This means that on the wedge:

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

after 5 seconds the program generates another number( for example: 6.5)

this means that the properties of the wedge must change.

By adding the for-loop in the update_figure method of the object 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()

By taking the difference between the old number and the new number and divide it by 10. You can easily change the gauge dynamically and slow by adding this for-loop and let the wedge draw itself 1O times ( with theta1 changing in 10 steps from the old number to the new number)with a sleep-time of 100 ms. If this explanation is not clear ask me and I'll try to explain it again.

Driedan
  • 255
  • 1
  • 5
  • 12