Rendu graphique en Python, Partie 1 - Découverte de Matplotlib et Turtle
Posté le 07/04/2020 18:19
Bonjour à toi, visiteur de ce forum. Casio vient de publier sa mise à jour Python incluant les modules matplotl et turtle pour Graph 35+E II et Graph 90+E. Alors voyons ce que ça donne en vrai !
Les modules avaient été
annoncés dans la dernière newsletter de Casio en Février, et les exemples proposés démontraient une
compatibilité totale entre calculatrice et PC sur les fonctions simples des deux modules. On se félicite d'avoir accès à des modules cross-platform qui faciliteront grandement le travail des professeurs et des élèves. Notons que Numworks a fait le même choix avec des bons résultats. Voyez les
tests de Critor sur ce point.
La mise à jour est désormais en ligne et porte un nouveau numéro de version de l'OS. La version supportant les modules matplotl et turtle est :
• La
version 3.30 sur Graph 35+E II,
• La
version 3.40 sur Graph 90+E.
La mise à jour est
disponible en ligne sur le site de Casio et consiste, comme d'habitude, en un fichier exécutable permettant d'installer le nouvel OS sur ta calculatrice. Mais cette fois, ce n'est pas tout ! Il y a aussi deux scripts
matplotl.py et
turtle.py qui vont avec et qui sont téléchargeables
dans la section ressources du site Casio Éducation. Il faut un compte pour y accéder, alors à la place vous pouvez aussi les télécharger
directement sur cette page (archive zip).
Mais alors, si l'OS n'intègre pas directement matplotlib et turtle, pourrait-il contenir d'autres fonctions utiles pour développer des jeux ?
Nous allons voir tout ça ensemble. J'ai installé les modules sur ma Graph 90+E et ma Graph 35+E II, c'est le moment de jouer avec ! Je vais montrer des images de la Graph 35+E II parce qu'elle est beaucoup plus pratique pour faire des captures, mais ce que je raconte concerne les deux modèles.
Changements depuis la version précédente
La Graph 35+E II affiche désormais le message "Des extensions supprimées par Réinitialisation1 sont installées". Ce message a été ajouté sur la Graph 90+E il y a un moment et signifie en gros que les add-ins sont désactivés en mode examen. Rien d'inattendu ici !
La Graph 35+E II est désormais en OS 3.30 et contient les deux scripts
matplot.py et
turtle.py une fois qu'ils ont été transférés. Pareil pour la Graph 90+E dont l'OS est maintenant appelé 3.40.
Attention à ne pas confondre l'OS 3.30 de la Graph 35+E II et l'OS 3.30 de la Graph 90+E !
Exemples standard de matplotlib et turtle
Regardons un exemple présenté sur la Graph 90+E dans la newsletter, mais sur la Graph 35+E II : celui de l'histogramme.
Voici le code et ce que ça donne sur la calculatrice :
import matplotl as p
x=[119.1,119.3,119.5,119.6,119.9,120.0,120.1,120.3,120.4]
y=[1,3,4,3,1,3,1,3,1]
p.bar(x,y,0.08)
p.show()
C'est un peu serré... mais pas si mal ! Les labels de l'axes des abscisses ne font pas de cadeau, ils sont à la fois longs et nombreux sur cet exemple.
Cet exemple met longtemps à s'exécuter. Pas loin de 9 secondes, ce qui est... normal ! Eh oui, il faut charger
matplot.py en entier, et c'est un script de 40000 caractères. C'est de loin ce qui prend le plus longtemps (pour le voir on peut mettre deux listes
x et
y de taille différente, et l'erreur met longtemps à arriver).
Voyons voir ce qui se passe du côté de turtle. J'ai codé le même script de flocon de Koch que présenté avant.
from turtle import *
def koch(n,l):
if n==0:
forward(l)
else:
koch(n-1,l/3)
left(60)
koch(n-1,l/3)
right(120)
koch(n-1,l/3)
left(60)
koch(n-1,l/3)
pencolor("black")
penup()
goto(-120,-10)
pendown()
koch(4,120)
Ce script qui effectue 81 tracés de lignes et des rotations met 3 secondes à charger turtle et... presque une minute à faire le dessin ! Mais là encore ça ne condamne pas les performances, car...
• turtle rafraîchit l'écran à chaque ligne, ce qui gâche des ressources (on en reparlera).
• turtle redessine la tortue à chaque ligne, ce qui est plus long que de tracer la ligne (!)
• Et surtout turtle fait beaucoup de calculs trigonométriques car la tortue fonctionne sur un système d'angles.
Alors voyons ce qui se cache derrière ses modules de dessin et ce que les performances sont vraiment.
La vraie bibliothèque de dessin en Python, casioplot
Comme annoncé dans la newsletter, les modules
matplotl et
turtle reposent sur un module de dessin spécifique appelé
casioplot. C'est lui qui est inclus dans la mise à jour de l'OS !
Que contient ce module ? Pour le savoir, il suffit de lire
matplotl.py et
turtle.py. C'est ce que j'ai fait pour vous. Voici le verdict !
casioplot est un module de dessin bas-niveau qui écrit très certainement directement dans la VRAM. Il permet de dessiner à l'écran avec des positions en pixels. Les fonctions sont les suivantes :
•
casioplot.clear_screen()
•
casioplot.set_pixel(x,y,(R,G,B))
•
casioplot.get_pixel(x,y)
•
casioplot.draw_string(x,y,text,(R,G,B),size)
•
casioplot.show_screen()
Ce sont les fonctions de base que l'on pouvait attendre. Il n'y a pas de tracé de ligne ou de cercle, car matplotl et turtle le recodent. Les lignes sont tracées avec l'algorithme de Bresenham, les cercles avec... de la trigo ! (Ce qui est une très mauvaise idée car c'est extrêmement lent, des vrais algorithmes comme
celui du point médian sont faits pour ça.)
Pour dessiner, on a donc
set_pixel() et
draw_string(), qui peut utiliser à la fois la petite police et la grande ! On peut lire la couleur des pixels à l'écran avec
get_pixel(), ce qui est un ajout assez cool ! Les couleurs sont en RGB avec chaque composante entre 0 et 255. C'est le cas également sur la Graph 35+E II, les couleurs sont justes approximées par du noir et blanc selon ce qui est le plus proche.
L'existence de
casioplot.show_screen() est très importante ! Contrairement au Basic, les dessins tracés avec casioplot ne sont pas affichés immédiatement. Cette technique s'appelle le
double buffering et a plusieurs avantages :
• Ça évite que l'utilisateur voie un dessin inachevé, car tu peux n'appeler
show_screen() qu'une fois le dessin fini.
• C'est beaucoup plus rapide car dessiner va souvent bien plus vite qu'afficher à l'écran, et donc on évite beaucoup de travail en plus.
Voici un petit programme pour donner le ton.
from casioplot import *
B=(0,0,0)
W=(255,255,255)
clear_screen()
set_pixel(1, 1, B)
for x in range(10):
set_pixel(x+1,3,B)
for y in range(40):
for x in range(10):
set_pixel(x+1,y+5,B)
draw_string(20,1,"Hello,",B,"large")
draw_string(20,11,"World!",B,"small")
img = b'\x04@"\x00\x0e\xa6W\x00\x0e\xafW\x00\x05\x1f\x89\x00u/J\xc0\xf5F*\xe0'+\
b'\xe4\xc92\xe0\x8cP\xa1 \x8c{\xe1 \x8c\xbf\xb1 \x8c\xb1\xb1 \x9c\x950'+\
b'\xa0\x9e\xb1\x90\xa0\x8e\x7f\xc3 \xc3\xfb\xfc`\xe0\x1d\xc0\xe0\xbf\x12'+\
b'\x1f\xa0_\t\x1f@ \x89 \x80\x1f\x92?\x00'
for y in range(20):
for x in range(27):
offset = y * 4 + (x // 8)
bit = 0x80 >> (x & 7)
if img[offset] & bit:
set_pixel(x+30,y+30,B)
show_screen()
Boum! Moins d'une demi-seconde pour importer le module, faire le tracé, et mettre à jour l'écran. C'est
de très, très loin plus rapide que le Basic Casio pour le dessin ! Comme on l'avait soupçonné, les performances réduites de matplotl et turtle ne sont pas à cause du dessin pur, ce qui ouvre beaucoup de possibilités pour des programmes plus ludiques !
Pour ceux qui se demandent, les caractères bizarres au milieu du script sont un encodage bitmap de l'image du château, qui vient de
SwordBurstZero.
Il y a beaucoup, beaucoup plus de choses à dire sur ces bibliothèques. On va s'arrêter là pour aujourd'hui mais on prendra bien sûr le temps d'y revenir !
À venir dans les prochains articles
Dans la suite, on regardera quelles sont les différences entre les versions Graph 35+E II et Graph 90+E de matplotlib, turtle et casioplot.
On s'intéressera aussi aux performances plus en détail, avec des exemples plus simples pour tester si le tracé, le dessin ou l'exécution du Python sont les facteurs limitants. Si vous avez déjà essayé chez vous, partagez vos résultats dans les commentaires !
Enfin, on organisera un petit concours consistant à programmer des
démos (petits programmes graphiques qui tournent généralement en boucle et affichent des dessins ou animations rigolos) avec ces modules, pour voir jusqu'où vous pouvez abuser de ces nouvelles fonctionnalités.
À bientôt sur Planète Casio !
Liens de téléchargement :
•
Téléchargement de la mise à jour
•
Scripts matplotl.py et turtle.py pour Graph 35+E II et Graph 90+E
•
Section ressources de Casio Éducation
Fichier joint
Citer : Posté le 07/04/2020 18:33 | #
Je trouve tres etonnant que les traces de segments, cercles, etc. aient ete codes en Python plutot qu'en C. Je soupconne que le developpement a ete pilote par la France et externalise, avec peu d'implication de la R&D Casio, le module micropython casioplot etant extremement basique.
Pas de rectangle parallele aux axes, pas de polygone, pas de forme remplie, ca laisse une belle avance a KhiCAS!
Citer : Posté le 07/04/2020 18:35 | #
C'est l'impression que j'avais, vu que les deux scripts turtle.py et matplotl.py en question ne sont pas inclus dans la mise à jour et récupérables uniquement sur le site français de Casio.
Gros inconvénient aussi, comme ce sont donc des fichiers à rajouter ils sont probablement inutilisables en mode examen.
Citer : Posté le 07/04/2020 18:59 | #
Peut-etre que ca va etre implemente en C plus tard, j'imagine qu'il va y avoir des remontees sur le temps de chargement du module. Mais peut-etre pas, parce que c'est considere comme secondaire.
Citer : Posté le 07/04/2020 19:03 | #
Des benchmarks sur 90+e sans overclock.
Pas très précis, mais devraient vous donner une idée des possibilités de ce nouveau module
Je ne suis pas un timer, ils seront donc précis à la seconde près.
from casioplot import *
input()
for i in range(<précision>):
<code>
10 000 set_pixel(0, 0) : 3 secondes (~0.3 ms)
10 000 get_pixel(0, 0) : 8 secondes (~0.8 ms)
1 000 clear_screen() : 6 secondes (soit ~1 ms)
2 000 draw_string(0, 0, "PC the best", (255,0,0), "small") : 2 secondes (~1 ms)
2 000 draw_string(0, 0, "PC the best", (255,0,0)) : 3 secondes (~2 ms)
2 000 draw_string(0, 0, "PC the best") : 3 secondes (~2 ms)
2 000 draw_string(0, 0, "PC the best", (255,0,0), "large") : 5 secondes (~3 ms)
A noter que 3 tailles de police sont disponibles sur 90+e
Citer : Posté le 08/04/2020 07:44 | #
Très pratique, le chargement d'images ! cela offre des perspectives ! En python, on a au moins accès à la programmation orientée objet on-calc, ce qui devrait aboutir à des programmes très chouettes, éditables sur ordi et dont le code est compréhensible.
Je me demandais si on pouvait ouvrir les fichiers matplotl.py et turtle.py pour voir la manière dont ils ont ajouté les modules, et si on pouvait pas les optimiser, ou juste trifouiller dedans !
Dijkstra - The Witcher
Citer : Posté le 08/04/2020 08:15 | #
Je me demandais si on pouvait ouvrir les fichiers matplotl.py et turtle.py pour voir la manière dont ils ont ajouté les modules, et si on pouvait pas les optimiser, ou juste trifouiller dedans !
Et bien tu est servi Lightmare
Ajouté le 08/04/2020 à 08:18 :
De mon coté la commande clear_screen() fonctionne mais n'est pas affichée dans le catalogue
De plus j'ai un résultat bizarre avec:
cp.set_pixel(10, 10, (255, 0, 0))
print(cp.get_pixel(10, 10))
Le code me renvoie (248, 0, 0)
-Planétarium 2
Citer : Posté le 08/04/2020 09:28 | #
De plus j'ai un résultat bizarre avec:
cp.set_pixel(10, 10, (255, 0, 0))
print(cp.get_pixel(10, 10))
Le code me renvoie (248, 0, 0)
Le rouge n'est pas vraiment rouge :p, mais c'est assez étonnant comme résultat xD
Citer : Posté le 08/04/2020 09:53 | #
Oui en effet
-Planétarium 2
Citer : Posté le 08/04/2020 09:59 | #
C'est normal, avec C.Basic c'est comme ca aussi. Les couleurs sont en 16 bits et pas en 24bits, donc ca monte jusqu'à 248 mais pas 255
Dijkstra - The Witcher
Citer : Posté le 08/04/2020 10:00 | #
C'est normal, l'écran de la calculatrice est en RGB565, donc les couleurs ne peuvent pas réellement pendre 256 valeurs. Le rouge ne peut en prendre que 32, et donc 255 est approximé par 248. Casio a quand même voulu utiliser le format à 256 valeurs pour la compatibilité avec l'ordinateur !
Ajouté le 08/04/2020 à 10:53 :
Je me demandais si on pouvait ouvrir les fichiers matplotl.py et turtle.py pour voir la manière dont ils ont ajouté les modules, et si on pouvait pas les optimiser, ou juste trifouiller dedans !
On peut totalement faire ça. On peut lire le code, on peut optimiser le code, on peut ajouter des fonctions, et on peut partager les versions modifiées. N'est-ce pas incroyable ?
Citer : Posté le 08/04/2020 10:57 | #
D'ailleurs, si on ne peut pas ajouter de modules, on peut pas les recréer sous le nom "turtle" ou "matplotl" et ca devrait fonctionner ?
Dijkstra - The Witcher
Citer : Posté le 08/04/2020 11:00 | #
Pourquoi ne pourrais-tu pas les ajouter ?
Si tu recrées maltplotl.py et turtle.py avec du code à toi, oui ça marchera. Ici Casio ne fait que nous fournir sa version de ces modules.
Citer : Posté le 08/04/2020 11:04 | #
ce qui veut dire qu'ils n'ont pas fait de système d'ajout de modules dynamiques
mais au moins on pourra avoir de vraies libs python pour faire des graphismes ! sachant qu'on ne peut toujours pas ouvrir de fichiers extérieurs ou autre...
que permet de plus l'utilisation de ces modules pour implanter nos fonctions plus que les recréer dans un autre fichier ?
Dijkstra - The Witcher
Citer : Posté le 08/04/2020 11:07 | #
@KikooDX : excellent ces benchmarks ! Je suppose que tu mesures le temps à la main, du coup est-ce qu'il y a moyen de faire pareil sur une durée plus longue (~1 minute) pour minimiser l'incertitude due à ta mesure ?
Cela dit, c'est clairement beaucoup plus rapide que le Basic Casio, et ça c'est top !
Citer : Posté le 08/04/2020 11:09 | #
@KikooDX : excellent ces benchmarks ! Je suppose que tu mesures le temps à la main, du coup est-ce qu'il y a moyen de faire pareil sur une durée plus longue (~1 minute) pour minimiser l'incertitude due à ta mesure ?
Cela dit, c'est clairement beaucoup plus rapide que le Basic Casio, et ça c'est top !
Je ferai des tests sur des durées 10 fois plus longues, c'est vrai que ça manque de précision. Merci !
Citer : Posté le 08/04/2020 11:24 | #
On dirait déjà qu'un librairie de base ait été ajoutée : casioplot. je sais pas si elle était présente avant, mais en tout cas elle joue un gros rôle dans les fonctionnalités graphiques des modules.EDIT : j'ai pas lu un paragraphe
Dijkstra - The Witcher
Citer : Posté le 08/04/2020 11:31 | #
J'ai retesté les valeurs, voici mes résultats :
10 000 set_pixel(0, 0, (i%2, 0, 0)) : 6 secondes (~0.6 ms)
1 000 000 set_pixel(0, 0) : 25 secondes (~0.025 ms)
10 000 get_pixel(0, 0) : 6 secondes (~0.6 ms)
10 000 clear_screen() : 55 secondes (soit ~5.5 ms)
Grosse erreur sur set_pixel, qu'ils ont apparament optimisé pour qu'il ne redessine pas quand le pixel est inchangé.
Citer : Posté le 08/04/2020 11:35 | #
Ça m'étonnerait beaucoup, car changer la valeur d'un pixel c'est immédiat. Tester si la nouvelle couleur est la même que l'ancienne est plus long que juste écrire la valeur sans se casser la tête !
Par contre, il peut y avoir d'autres effets comme le cache ou le fait que si le modulo n'est pas optimisé par Python en i&1 alors il est très lent.
Citer : Posté le 08/04/2020 11:48 | #
je vais tenter le raytracing sur python pour calculatrice ! on devrait s'approcher des perfs de C.Basic avec un code plus propre.
Dijkstra - The Witcher
Citer : Posté le 08/04/2020 11:53 | #
Voilà désolé, toujours dans des conditions informatiques très précaires suite à une panne d'ordi hélas des plus graves lundi matin, mais j'ai pu mettre en avant cette fantastique mise à jour et rajouter la référence, enfin :
https://tiplanet.org/forum/viewtopic.php?p=252337#p252337
Quel dommage que turtle.py et matplotl.py ne marchent pas en mode examen, c'est hélas également un gros défaut pour la France.