Si è visto nella prima parte del corso che le proprietà di un oggetto grafico realizzato con plot possono essere cambiate.

Per esempio

>> x = 0:1:10;
>> y = x.^2;
>> plot(x,y,'o-')

disegna un grafico  in cui i marker sono dei pallini vuoti e la linea che li unisce è tratteggiata.

È possibile chiamare la funzione plot facendole restituire un oggetto di tipo struct:

 

>> p = plot(x,y,'o-')

p =
Line with properties:
Color: [0 0.4470 0.7410]
LineStyle: '--'
LineWidth: 0.5000
Marker: 'o'
MarkerSize: 6
MarkerFaceColor: 'none'
XData: [0 1 2 3 4 5 6 7 8 9 10]
YData: [0 1 4 9 16 25 36 49 64 81 100]

Show all properties

ed è evidente che la variabile p contiene tutte le informazioni relative al grafico realizzato. La voce "all properties" è cliccabile e se viene premuta compaiono tutte le proprietà:

p = 
Line with properties:
Color: [0 0.4470 0.7410]
LineStyle: '--'
LineWidth: 0.5000
Marker: 'o'
MarkerSize: 6
MarkerFaceColor: 'none'
XData: [0 1 2 3 4 5 6 7 8 9 10]
YData: [0 1 4 9 16 25 36 49 64 81 100]

Show all properties
AlignVertexCenters: off
Annotation: [1×1 matlab.graphics.eventdata.Annotation]
BeingDeleted: off
BusyAction: 'queue'
ButtonDownFcn: ''
Children: [0×0 GraphicsPlaceholder]
Clipping: on
Color: [0 0.4470 0.7410]
ColorMode: 'auto'
ContextMenu: [0×0 GraphicsPlaceholder]
CreateFcn: ''
DataTipTemplate: [1×1 matlab.graphics.datatip.DataTipTemplate]
DeleteFcn: ''
DisplayName: ''
HandleVisibility: 'on'
HitTest: on
Interruptible: on
LineJoin: 'round'
LineStyle: '--'
LineStyleMode: 'manual'
LineWidth: 0.5000
Marker: 'o'
MarkerEdgeColor: 'auto'
MarkerFaceColor: 'none'
MarkerIndices: [1 2 3 4 5 6 7 8 9 10 11]
MarkerMode: 'manual'
MarkerSize: 6
Parent: [1×1 Axes]
PickableParts: 'visible'
Selected: off
SelectionHighlight: on
SeriesIndex: 1
SourceTable: [0×0 table]
Tag: ''
Type: 'line'
UserData: []
Visible: on
XData: [0 1 2 3 4 5 6 7 8 9 10]
XDataMode: 'manual'
XDataSource: ''
XVariable: ''
YData: [0 1 4 9 16 25 36 49 64 81 100]
YDataMode: 'manual'
YDataSource: ''
YVariable: ''
ZData: [1×0 double]
ZDataMode: 'auto'
ZDataSource: ''
ZVariable: ''f

In effetti è possibile operare sulle proprietà di una figura come si opera su una struct. Per esempio:

>> p.LineWidth = 2;

modifica lo spessore della linea da 0.5 pt (valore di default) a 2 pt.

Grazie a questo meccanismo è possibile cambiare l'aspetto di una figura a proprio piacimento.

Tuttavia,se  il cambiamento delle proprietà di una figura possono avvenire in un modo simile a cambiare un valore di una struct, le cose non stanno proprio così. Se infatti la struct "p" restituita da plot() fosse solamente una struct, l'aggiornamento della figura NON dovrebbe essere automatico.

Questo ci fa capire che le cose non stanno esattamente come appena detto.

Per chiarire cosa sta succedendo è necessario dire che Matlab oltre agli oggetti di tipo struct supporta anche degli oggetti di tipo class. Le class (classi) possono essere pensate (con buona approssimazione) come a particolari struct dotate non solo di proprietà (i valori), ma anche di metodi, ovvero di funzioni che permettono di operare sulle proprietà (cioè di modificare i valori).

Nel caso specifico, l'assegnazione di un valore ad una proprietà di un oggetto grafico usando la notazione punto (come fatto precedentemente)

 

>> p.LineWidth = 2;

equivale a richiamare un metodo (il metodo set) che aggiorna il valore della proprietà "LineWidth" dell’oggetto grafico (modifica lo spessore della linea a 2 pt) e ridisegna il grafico.

 

È possibile ottenere la lista delle proprietà e dei metodi di una classe mediante le funzioni properties e methods. Nel caso di "p" si ha:

 

>> properties(p)

Properties for class matlab.graphics.chart.primitive.Line:
XData
XDataMode
XVariable
YData
YDataMode
YVariable
ZData
ZDataMode
ZVariable
XDataSource
YDataSource
ZDataSource
Color
ColorMode
LineStyle
LineStyleMode
LineWidth
Marker
MarkerMode
MarkerSize
MarkerEdgeColor
MarkerFaceColor
Clipping
MarkerIndices
AlignVertexCenters
LineJoin
Children
Parent
Visible
HandleVisibility
ButtonDownFcn
ContextMenu
BusyAction
BeingDeleted
Interruptible
CreateFcn
DeleteFcn
Type
Tag
UserData
Selected
SelectionHighlight
HitTest
PickableParts
DisplayName
Annotation
SeriesIndex
DataTipTemplate
SourceTable

>> methods(p)

Methods for class matlab.graphics.chart.primitive.Line:
Line double get ne
addlistener eq isprop reset
addprop findobj java set
Static methods:
loadobj
Methods of matlab.graphics.chart.primitive.Line inherited from handle.

La lettura delle risposte che restitutisce Matlab ci fa capire due cose:

  1.  In realtà "p" non è una classe (che si chiama matlab.graphics.chart.primitive.Line),  ma bensì un handle (puntatore) alla classe matlab.graphics.chart.primitive.Line. L'utilizzo degli handle semplifica l'accesso alle proprietà e ai metodi di una classe.
  2. Abbiamo a che fare con classi che contengono altre classi. Nel nostro caso, per esempio, la classe Line che contiene le caratteristiche con cui sono disegnate le linee (cioè la proprietà "LineWidth") in una figura è contenuta nella classe primitive che a sua volta è parte  della classe chart e così via fino alla classe matlab che contiene tutte

Prima di proseguire, vediamo di capire perché l'utilizzo degli handle semplifica l'accesso alle proprietà e ai metodi di una classe. La risposta è molto semplice una volta osservato che i due comandi seguenti sono equivalenti:

>> p.LineWidth = 2; 
>> matlab.graphics.chart.primitive.Line.LineWidth = 2;

nel secondo caso per assegnare lo spessore della linea è necessario conoscere tutta la struttura di incapsulamento delle classi, molto meglio usare l'handle!

Per riuscire a cambiare a proprio piacimento l'aspetto di una figura è necessario comprendere come gli oggetti grafici sono organizzati in Matlab.

Ogni elemento grafico in Matlab è descritto tramite un oggetto grafico a partire dalla class Root (radice).

Ogni finestra grafica è una class "Figure" che viene aggiunta alla class "Root". Se si hanno più finestre grafiche aperte, queste  vengono aggiunte come vettori associati alla root class "matlab".

Con il comando

>> p = plot(x,y);

viene creato uno degli oggetti Chart and Primitive Objects (uno degli oggetti grafici più bassi). In conseguenza a questo vengono automaticamente creati un oggetto  Axes e un oggetto Figure.

A partire dall'handle "p" è possibile identificare gli oggetti grafici Figure e Axes che vengono automaticamente creati in due modi:

1- Scorrendo verso l'alto usando la proprietà Parent

>> x = 0:1:10;
>> y = x.^2;
>> p = plot(x,y);
>> asse = p.Parent % ricerca della classe Axes
 
asse =
Axes with properties:
XLim: [0 10]
YLim: [0 100]
XScale: 'linear'
YScale: 'linear'
GridLineStyle: '-'
Position: [0.1300 0.1100 0.7750 0.8150]
Units: 'normalized'

Show all properties
 
>> figura = asse.Parent % ricerca della classe Figure
 
figura =
Figure (1) with properties:
Number: 1
Name: ''
Color: [0.9400 0.9400 0.9400]
Position: [360 278 560 420]
Units: 'pixels'

Show all properties
 
>> radice = figura.Parent % ricerca della classe Root
 
radice=
Graphics Root with properties:
CurrentFigure: [1×1 Figure]
ScreenPixelsPerInch: 96
ScreenSize: [1 1 1280 800]
MonitorPositions: [2×4 double]
Units: 'pixels'

Show all properties
 
>> radice.Parent % ricerca della classe superiore che non esiste
 
ans =
0×0 empty GraphicsPlaceholder array.

2- Usando le funzioni gca (get current Axes) e gcf (get current Figure)

>> x = 0:1:10;
>> y = x.^2;
>> p = plot(x,y);
>> asse = gca % ricerca della classe Asse
 
asse =
Axes with properties:
XLim: [0 10]
YLim: [0 100]
XScale: 'linear'
YScale: 'linear'
GridLineStyle: '-'
Position: [0.1300 0.1100 0.7750 0.8150]
Units: 'normalized'

Show all properties
 
>> figura = gcf % ricerca della classe Figure
 
figura =
Figure (1) with properties:
Number: 1
Name: ''
Color: [0.9400 0.9400 0.9400]
Position: [360 278 560 420]
Units: 'pixels'

Show all properties

Figure e Axes si possono creare esplicitamente mediante le funzioni figure e axes (in minuscolo). Ad esempio figure(3) crea una finestra grafica con indice 3

>> fid = figure(3)

fid =
Figure (3) with properties:
Number: 3
Name: ''
Color: [0.9400 0.9400 0.9400]
Position: [360 278 560 420]
Units: 'pixels'

Show all properties

La finestra grafica generata è la seguente:

Se vogliamo inserire un sistema cartesiano per disegnarvi dentro è sufficiente invocare sucessivamente la funzione axes()

>> aid = axes()

aid =
Axes with properties:
XLim: [0 1]
YLim: [0 1]
XScale: 'linear'
YScale: 'linear'
GridLineStyle: '-'
Position: [0.1300 0.1100 0.7750 0.8150]
Units: 'normalized'

Show all properties

e nella finestra grafica compare un sistema di assi cartesiani:

Si vogliono qui sotto riportare nuovamente alcune delle proprietà principali degli oggetti grafici visti.

plot

  • Color (colore): definito mediante un vettore di 3 valori RGB normalizzati a 1
  • LineStyle (stile della linea): - , -- , : , -. rispettivamente per linea continua, tratteggiata, puntinata o tratto-punto
  • LineWidth (spessore della linea): valore in punti tipografici (pt)
  • Marker (tipo di marker): o,+,*,.,x,s,d,^,v,>,<,p,h
  • MarkerSize (dimensione del marker): valore in punti tipografici (pt)

Axes

  • Box: booleano per attivare/disattivare le linee esterne che definiscono l’area di visualizzazione
  • DataAspectRatio: vettore di 3 elementi che definisce il fattore di scala degli assi rispetto alla figura. Ad esempio, con DataAspectRatio=[1 1 1] un cerchio in 2D non appare deformato graficamente
  • FontName, FontSize: per definire il tipo e la dimensione del font utilizzato per i numeri/testi visualizzati lungo gli assi
  • Position: vettore di 4 elementi [x0,y0,width,height], di default normalizzati a 1, che definiscono la posizione degli assi nella figura
  • TickLabelInterpreter: interprete dei numeri/testi visualizzati lungo gli assi, può essere ’tex’ o ’latex’
  • TickDir: direzione dei ticks, può essere ’in’, ’out’ o ’both’
  • XLim, YLim, (ZLim): vettori di 2 valori che definiscono gli intervalli di visualizzazione lungo le 3 dimensioni
  • XScale, YScale, (ZScale): ’linear’ o ’log’ per scale lineari o logaritmiche
  • XGrid, YGrid, (ZGrid), XMinorGrid, YMinorGrid, (ZMinorGrid): booleani per attivare/disattivare la griglia in corrispondenza dei ticks e dei minorticks
  • Title, XLabel, YLabel, (ZLabel): oggetti grafici primitivi, quindi caratterizzati a loro volta da altre proprietà, per i testi da visualizzare come titolo e denominazione degli assi.
Ultime modifiche: lunedì, 1 gennaio 2024, 18:56