PyQt Lab est un outil puissant qui permet aux utilisateurs de créer des graphiques mathématiques complexes à l’aide de Pyqtgraph. Dans cet article, nous allons vous montrer comment afficher la courbe du corps noir et la paramétrer à l’aide d’un slider dans un graphique Pyqtgraph. Nous allons également vous expliquer comment utiliser cet outil pour créer des graphiques mathématiques plus complexes et plus intéressants.
PyQt Lab’ : Graphiques Math : Pyqtgraph : Afficher la courbe du corps noir et la paramétrer à l’aide d’un slider dans un graphique Pyqtgraph.
Par X. HINAULT – Juin 2013

Ce que l’on va faire ici
- Afficher la courbe du corps noir et la paramétrer à l’aide d’un slider dans un graphique pyqtgraph.
Pré-requis
- python 2.7
- pyqt4.x
- pyqtgraph
- numpy
- scipy
Infos utiles
- La courbe du corps noir relie l’intensité lumineuse spectrale d’un corps chauffé.
- Cette loi a été découverte par Planck et a résolu la fameuse « catastrophe ultra-violette », mettant en évidence la notion de « quantum d’énergie », ouvrant ainsi la voie à la relativité restreinte et à la physique quantique.
- La formule est assez complexe mettant en jeu notamment la constante de Planck, la vitesse de la lumière et la constante Boltzmann :

- Ce code est facilité grâce à l’utilisation de la librairie Scipy qui intégre les constantes physiques principales.
Le fichier d’interface *.ui
<ui version=« 4.0 »>
<class>Form</class>
<widget class=« QWidget » name=« Form »>
<property name=« geometry »>
<rect>
<x>0</x>
<y>0</y>
<width>609</width>
<height>477</height>
</rect>
</property>
<property name=« windowTitle »>
<string>PyQt + pyqtgraph : Courbe et Sliders : loi corps noir</string>
</property>
<widget class=« QSlider » name=« horizontalSlider »>
<property name=« geometry »>
<rect>
<x>5</x>
<y>415</y>
<width>596</width>
<height>19</height>
</rect>
</property>
<property name=« minimum »>
<number>1</number>
</property>
<property name=« maximum »>
<number>10000</number>
</property>
<property name=« singleStep »>
<number>100</number>
</property>
<property name=« pageStep »>
<number>1000</number>
</property>
<property name=« value »>
<number>5000</number>
</property>
<property name=« orientation »>
<enum>Qt::Horizontal</enum>
</property>
<property name=« tickPosition »>
<enum>QSlider::NoTicks</enum>
</property>
<property name=« tickInterval »>
<number>1</number>
</property>
</widget>
<widget class=« QLabel » name=« label_T »>
<property name=« geometry »>
<rect>
<x>230</x>
<y>450</y>
<width>51</width>
<height>13</height>
</rect>
</property>
<property name=« text »>
<string>Temp =</string>
</property>
</widget>
<widget class=« QLCDNumber » name=« lcdNumber_w »>
<property name=« geometry »>
<rect>
<x>285</x>
<y>445</y>
<width>64</width>
<height>23</height>
</rect>
</property>
<property name=« styleSheet »>
<string notr=« true »>background-color: rgb(170, 255, 255);
color: rgb(0, 0, 127);</string>
</property>
<property name=« segmentStyle »>
<enum>QLCDNumber::Flat</enum>
</property>
<property name=« intValue » stdset=« 0 »>
<number>5000</number>
</property>
</widget>
<widget class=« PlotWidget » name=« plotwidget »>
<property name=« geometry »>
<rect>
<x>5</x>
<y>10</y>
<width>600</width>
<height>400</height>
</rect>
</property>
</widget>
<widget class=« QLabel » name=« label_T_units »>
<property name=« geometry »>
<rect>
<x>355</x>
<y>450</y>
<width>51</width>
<height>13</height>
</rect>
</property>
<property name=« text »>
<string>Kelvins</string>
</property>
</widget>
</widget>
<customwidgets>
<customwidget>
<class>PlotWidget</class>
<extends>QGraphicsView</extends>
<header>pyqtgraph</header>
</customwidget>
</customwidgets>
<resources/>
<connections>
<connection>
<sender>horizontalSlider</sender>
<signal>valueChanged(int)</signal>
<receiver>lcdNumber_w</receiver>
<slot>display(int)</slot>
<hints>
<hint type=« sourcelabel »>
<x>181</x>
<y>433</y>
</hint>
<hint type=« destinationlabel »>
<x>309</x>
<y>460</y>
</hint>
</hints>
</connection>
</connections>
</ui>
Le fichier d’interface *.py
- Fichier obtenu automatiquement avec l’utilitaire pyuic4 à partir du fichier *.ui créé avec QtDesigner :
# Form implementation generated from reading ui file
#
# Created: Fri Sep 6 15:34:14 2013
# by: PyQt4 UI code generator 4.9.1
#
# WARNING! All changes made in this file will be lost!
from PyQt4 import QtCore, QtGui
try:
_fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
_fromUtf8 = lambda s: s
class Ui_Form(object):
def setupUi(self, Form):
Form.setObjectName(_fromUtf8(« Form »))
Form.resize(609, 477)
self.horizontalSlider = QtGui.QSlider(Form)
self.horizontalSlider.setGeometry(QtCore.QRect(5, 415, 596, 19))
self.horizontalSlider.setMinimum(1)
self.horizontalSlider.setMaximum(10000)
self.horizontalSlider.setSingleStep(100)
self.horizontalSlider.setPageStep(1000)
self.horizontalSlider.setProperty(« value », 5000)
self.horizontalSlider.setOrientation(QtCore.Qt.Horizontal)
self.horizontalSlider.setTickPosition(QtGui.QSlider.NoTicks)
self.horizontalSlider.setTickInterval(1)
self.horizontalSlider.setObjectName(_fromUtf8(« horizontalSlider »))
self.label_T = QtGui.QLabel(Form)
self.label_T.setGeometry(QtCore.QRect(230, 450, 51, 13))
self.label_T.setObjectName(_fromUtf8(« label_T »))
self.lcdNumber_w = QtGui.QLCDNumber(Form)
self.lcdNumber_w.setGeometry(QtCore.QRect(285, 445, 64, 23))
self.lcdNumber_w.setStyleSheet(_fromUtf8(« background-color: rgb(170, 255, 255);\n«
« color: rgb(0, 0, 127); »))
self.lcdNumber_w.setSegmentStyle(QtGui.QLCDNumber.Flat)
self.lcdNumber_w.setProperty(« intValue », 5000)
self.lcdNumber_w.setObjectName(_fromUtf8(« lcdNumber_w »))
self.plotwidget = PlotWidget(Form)
self.plotwidget.setGeometry(QtCore.QRect(5, 10, 600, 400))
self.plotwidget.setObjectName(_fromUtf8(« plotwidget »))
self.label_T_units = QtGui.QLabel(Form)
self.label_T_units.setGeometry(QtCore.QRect(355, 450, 51, 13))
self.label_T_units.setObjectName(_fromUtf8(« label_T_units »))
self.retranslateUi(Form)
QtCore.QObject.connect(self.horizontalSlider, QtCore.SIGNAL(_fromUtf8(« valueChanged(int) »)), self.lcdNumber_w.display)
QtCore.QMetaObject.connectSlotsByName(Form)
def retranslateUi(self, Form):
Form.setWindowTitle(QtGui.QApplication.translate(« Form », « PyQt + pyqtgraph : Courbe et Sliders : loi corps noir », None, QtGui.QApplication.UnicodeUTF8))
self.label_T.setText(QtGui.QApplication.translate(« Form », « Temp = », None, QtGui.QApplication.UnicodeUTF8))
self.label_T_units.setText(QtGui.QApplication.translate(« Form », « Kelvins », None, QtGui.QApplication.UnicodeUTF8))
from pyqtgraph import PlotWidget
if __name__ == « __main__ »:
import sys
app = QtGui.QApplication(sys.argv)
Form = QtGui.QWidget()
ui = Ui_Form()
ui.setupUi(Form)
Form.show()
sys.exit(app.exec_())
Le fichier d’application *Main.py
# -*- coding: utf-8 -*-
# Par X. HINAULT – Tous droits réservés – GPLv3
# Déc 2012 – www.mon-club-elec.fr
# — importation des modules utiles —
from PyQt4.QtGui import *
from PyQt4.QtCore import * # inclut Qtimer..
import os,sys
import pyqtgraph as pg # pour accès à certaines constantes pyqtgraph, widget, etc…
# pas indisp. sinon car pyqtgraph est inclut par la déclaration QtDesigner de PlotWidget
import numpy
from scipy import e
from scipy.constants import codata
# — importation du fichier de description GUI —
from tuto_pyqt_pyqtgraph_courbe_corps_noir_slider import *
# classe principale contenant le code actif
class myApp(QWidget, Ui_Form): # la classe reçoit le Qwidget principal ET la classe définie dans test.py obtenu avec pyuic4
# Note : ici self représente la classe
def __init__(self, parent=None):
QWidget.__init__(self) # initialise le Qwidget principal
self.setupUi(parent) # Obligatoire
#– variables utiles —
#– variables utiles —
self.c=codata.value(‘speed of light in vacuum’) # constante vitesse de la lumière
print (« Constante vitesse de la lumière dans le vide = « + str(self.c))
self.h=codata.value(‘Planck constant’) # constante vitesse de la lumière
print (« Constante de Planck = « + str(self.h))
self.kb=codata.value(‘Boltzmann constant’) # constante de Boltzman
print (« Constante de Boltzmann = « + str(self.kb))
self.T=5000.0 # température en kelvin
#Ici, personnalisez vos widgets si nécessaire en utilisant les noms définis dans QtDesigner
#Réalisez les connexions supplémentaires entre signaux et slots
# les widgets sont désignés sous la forme self.nom en utilisant les noms définis dans QtDesigner
self.connect(self.horizontalSlider, SIGNAL(« valueChanged(int) »), self.horizontalSliderValueChanged)
# connecte le signal valueChanged de l’objet Slider à l’appel de la fonction voulue
# —— code actif initial ——
#– initialise données —
self.x = numpy.arange(0.1, 3000, 1) # plus précision réduite, plus rapide…
numpy.seterr(over=‘ignore’) # ignore warning overflow float
print(self.x.dtype)
print(self.x) # debug – affiche les valeurs x
# calcul Y = la loi du corps noir
self.y=(2*self.h*self.c**2/(self.x*1e-9)**5) *(pow(e,self.h*self.c/(self.x*1e-9*self.kb*self.T))–1)**–1
# debug
print(self.y) # debug – affiche les valeurs y
print(« max= »+str(numpy.amax(self.y))) # extrait la valeur maxi
index=numpy.argmax(self.y) # indice du max…
print(« indice max= »+str(index)) # affiche l’index valeur maxi
print(« longueur onde max= »+str(self.x[index])+ « nm ») # extrait la long onde du pic maxi
#– initialise la courbe —
self.plotwidget.hideAxis(‘left’) # masque axes – left, bottom, right, or top
self.plotwidget.setBackgroundBrush(QBrush(QColor(Qt.white))) # la classe PlotWidget est un GraphicsWidget qui est un QGraphics View
self.plotwidget.showGrid(x=True, y=True) # affiche la grille
#self.plotwidget.setInteractive(False) # fonction QGraphics View : pour inactiver interaction souris
self.plotwidget.getViewBox().setMouseMode(pg.ViewBox.RectMode) # fonction ViewBox pas accessible depuis PlotWidget : fixe selection par zone
self.plot1=self.plotwidget.plot(self.x,self.y, pen=(0,0,255)) # avec couleur – mémorise la courbe
# ——————— ligne violet 400nm ————————–
self.vLine400 = pg.InfiniteLine(angle=90, movable=False) # crée une ligne inifinie
self.vLine400.setPen(pg.mkPen(255,0,255)) # couleur de la ligne
self.plotwidget.addItem(self.vLine400, ignoreBounds=True) # ajoute la ligne au graphique – fonction ViewBox accessible depuis PlotItem
self.vLine400.setPos(400)
# ————————– ligne rouge 700 nm ————————–
self.vLine700 = pg.InfiniteLine(angle=90, movable=False) # crée une ligne inifinie
self.vLine700.setPen(pg.mkPen(255,0,0)) # couleur de la ligne
self.plotwidget.addItem(self.vLine700, ignoreBounds=True) # ajoute la ligne au graphique – fonction ViewBox accessible depuis PlotItem
self.vLine700.setPos(700)
# ————————– ligne IRA – 1400nm ————————–
self.vLine1400 = pg.InfiniteLine(angle=90, movable=False) # crée une ligne inifinie
self.vLine1400.setPen(pg.mkPen(127,0,0)) # couleur de la ligne
self.plotwidget.addItem(self.vLine1400, ignoreBounds=True) # ajoute la ligne au graphique – fonction ViewBox accessible depuis PlotItem
self.vLine1400.setPos(1400)
# ————————– ligne IRB – 3000nm ————————–
self.vLine3000 = pg.InfiniteLine(angle=90, movable=False) # crée une ligne inifinie
self.vLine3000.setPen(pg.mkPen(64,0,0)) # couleur de la ligne
self.plotwidget.addItem(self.vLine3000, ignoreBounds=True) # ajoute la ligne au graphique – fonction ViewBox accessible depuis PlotItem
self.vLine3000.setPos(3000)
# les fonctions appelées, utilisées par les signaux
def horizontalSliderValueChanged(self, valeur): # fonction appelée si changement valeur slider – reçoit la valeur courante
print(« Slider H modifié : valeur = « + str(valeur))
self.T=valeur
print self.T
self.y=(2*self.h*self.c**2/(self.x*1e-9)**5) *(pow(e,self.h*self.c/(self.x*1e-9*self.kb*self.T))–1)**–1
#self.y=(pow(self.x,3)/pow(e,self.x)-1)
print(self.y) # debug – affiche les valeurs y
print(« max= »+str(numpy.amax(self.y))) # extrait la valeur maxi
index=numpy.argmax(self.y) # indice du max…
print(« indice max= »+str(index)) # affiche l’index valeur maxi
print(« longueur onde max= »+str(self.x[index])+ « nm ») # extrait la long onde du pic maxi
self.plot1.setData(self.x,self.y) # met à jour les données
#— fonctions actives
# …
# fonction principale exécutant l’application Qt
def main(args):
a=QApplication(args) # crée l’objet application
f=QWidget() # crée le QWidget racine
c=myApp(f) # appelle la classe contenant le code de l’application
f.show() # affiche la fenêtre QWidget
r=a.exec_() # lance l’exécution de l’application
return r
# pour rendre le fichier *.py exécutable
if __name__==« __main__ »: # pour rendre le code exécutable
main(sys.argv) # appelle la fonction main
Utilisation
- Les 2 fichiers suivants sont à enregistrer dans un même répertoire, l’un en nom.py et l’autre en nomMain.py.
- Puis lancer l’application depuis Geany ou équivalent, en exécutant le fichier nomMain.py
- Faire défiler le slider entraîne la modification de la courbe.
Articles similaires:
- PyQt Lab’ : Graphiques Math : Pyqtgraph : Interagir avec une courbe d’un graphique pyqtgraph à l’aide de sliders.
- PyQt Lab’ : Graphiques Math : Pyqtgraph : Afficher un graphique Pyqtgraph vide avec des widgets de paramétrage.
- PyQt Lab’ : Graphiques Math : Afficher un graphique Pyqtgraph vide
- PyQt Lab’ : Graphiques Math : Pyqtgraph : Courbe paramétrique de la forme x=f(t) et y=f(t) dans un graphique Pyqtgraph.
- PyQt Lab’ : Graphiques Math : Pyqtgraph : Afficher une croix de ligne et le point courant sous le curseur de la souris dans un graphique Pyqtgraph.
Articles Liés
- PyQt Lab' : 3D avec OpenGL :
PyQt Lab est un outil puissant qui permet aux développeurs de créer des applications 3D…
- PyQt Lab' : Graphiques Math : Pyqtgraph : Afficher une courbe dans un graphique Pyqtgraph à partir d'une formule saisie dans un champ texte et enregistrement dans un fichier.
PyQt Lab est un outil puissant qui permet aux utilisateurs de créer des graphiques mathématiques…
- Javascript : Graphique Dygraphs simple
Le Javascript est un langage de programmation très populaire et puissant qui permet aux développeurs…