Grafici con tkinter

>>> LINK A PAGINA AGGIORNATA <<<

  • .
  • .
  • .
  • .
  • .
  • .
  • .
  • .
  • .
  • .
  • .
  • .
  • .
  • .
  • .
  • .
  • .
  • .
  • .
  • .
  • .
  • .
  • .
  • .

La libreria tkinter

La libreria grafica tk, di cui tkinter rappresenta l’interfaccia per Python, è relativamente semplice da usare, si trova già inclusa nelle distribuzioni Python per Windows, dispone delle funzionalità di base per creare una GUI, e il canvas grafico ha diverse cose molto interessanti.

In particolare il canvas non è una superficie bitmap (come quelle di pygame o pillow), ma si tratta di una superficie su cui “disegnare” oggetti vettoriali. Ogni oggetto grafico del canvas può essere spostato, cancellato, modificato, ha un suo Z-order e dispone di molte proprietà modificabili a runtime.

Ad esempio un grafico può essere formato da molte curve diverse, ogni curva può essere modificata in un colpo solo passandole una nuova sequenza di coordinate, o un nuovo colore ecc.

 

MyGraph

Per sfruttare le formule di traslazione di scala ho scritto una classe ‘MyGraph’, che permette di disegnare semplici grafici a partire da una serie di parametri (sfondo, assi, didascalie, colori, tipo di scala ecc). Basta descrivere i parametri tramite una classe, istanziare il grafico (passandogli i parametri), e creare una o più curve.

La classe usa due canvas uno dentro l’altro. Il canvas interno è quello su cui vengono rappresentate le curve. Fondamentalmente se ne sfrutta l’auto clipping in modo che nulla possa “sbordare” al di fuori di esso. Attorno ad esso vi è il canvas esterno dove vengono scritti i valori delle scale e le didascalie degli assi. Opzionalmente può essere disegnato il bordo del canvas interno.

La classe è molto semplice, tuttavia già con le poche combinazioni dei parametri disponibili permette di ottenere risultati visivamente interessanti:

 

grafici con mygraph

 

La classe parametri

L’aspetto base di un grafico con MyGraph si definisce con una classe di parametri, che in Python è il modo sintatticamente più compatto per raggruppare delle variabili:


class Gra:
    wid = 256              #larghezza in pixel
    hei = 192              #altezza in pixel
    margin_left = 48       #margini attorno al canvas
    margin_top = 50
    margin_right = 16
    margin_bottom = 60
   
    xmin = 0.1             #coordinate relative grafico
    xmax = 1000
    ymin = -1.5
    ymax = 3.5

    xlog = True            #scala X logaritmica
    ylog = False           #scala Y lineare
    paper = '#f0f0ff'      #colore sfondo grafico
    title='Y = log10(X)'   #Didascalia asse Y
    xtext='X'              #Didascalia asse X

    lsegm = 8              #segmenti estremi assi tratteggiati
    border = 1             #bordo visibile 0=invisibile
    axis = 1               #assi visibili  0=invisibili
    axis_color = 'gray'
    text = 1               #didascalie visibili
    origin = 1             #assi origine visibili
    origin_color = 'black'
    origin_arrow = 0       #origini senza frecce

    #assi orizzontali, 0 finale = tratteggiati
    oriz_axis = [-1., 0., 1., 2., 3.], 0

    #assi verticali, 1 finale = pieni
    vert_axis = [
        0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9,
        1, 2, 3, 4, 5, 6, 7, 8, 9,
        10, 20, 30, 40, 50, 60, 70, 80, 90,
        100, 200, 300, 400, 500, 600, 700, 800, 900], 1

    #maschere per formattazione valori didascalie su assi
    ymask = '{:.1f}'  #float una cifra dopo virgola
    xmask = '{}'      #stringa generica
    
    #valori da riportare sugli assi
    txt_y = -1, 0, 1, 2, 3
    txt_x = (0.1, 0.1), (1, 1), (10, 10), (100, 100), (1000, '1k')

 

Utilizzo


#-----------------------------------------------------------
#           Test classe MyGraph - By C.Fin 2018
#-----------------------------------------------------------
try:    import tkinter as tk
except: import Tkinter as tk
from mygraph import MyGraph
import math
#-----------------------------------------------------------
class Gra:
    #dimensioni canvas grafico
    wid = 256
    hei = 192
    margin_left = 48
    margin_top = 50
    margin_right = 16
    margin_bottom = 60

    #coordinate relative grafico
    xmin = 0
    xmax = 360
    ymin = -1.5
    ymax = 1.5

    xlog = False
    ylog = False
    paper = 'white'
    title='Y = sen(2X)'
    xtext='X'

    lsegm = 8
    border = 1
    axis = 1
    axis_color = '#D0D0D0'
    text = 1
    origin = 1
    origin_arrow = 0
    origin_color = 'black'
    oriz_axis = [-1, 1], 0
    vert_axis = [], 1

    ymask = '{:d}'
    xmask = '{:d}'
    txt_y = -1, 0, 1
    txt_x = (
        (0, 0), (90, 90), (180, 180),
        (270, 270), (360, 360)
        )
#-----------------------------------------------------------
root = tk.Tk();
gra = MyGraph(root, Gra)
gra.pack(expand=1)

minf = 0
maxf = 360
punti = 256
step = (maxf - minf) / (punti - 1.)
data = []
for punto in range(punti):
    x = minf + step*punto
    y = math.sin(math.radians(2*x))
    data.append((x, y))
gra.create_curve(data, fill='navy')

root.mainloop()

grafico con mygraph

Chiamando diverse volte il metodo ‘create_curve’ si possono disegnare più curve. Ogni volta viene restituito un valore che identifica l’oggetto curva nel canvas. Con il metodo ‘update_curve’ si può modificare la forma di una curva preesistente passando l’identificatore e la nuova sequenza di coordinate. Questo permette di creare animazioni o effettuare aggiornamenti senza bisogno di ridisegnare tutto.

 

 

 

(12/8/2018)

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *