Figures in Scilab (French)

Ce tutoriel est gracieusement contribué par Sylvain Lalot.

Introduction

L’idée du module est de progresser depuis la fonction de base “plot2d” jusqu’à l’obtention de figures évoluées tant au point de vue graphique que du point de vue de l’interactivité. L’idée du concepteur de ce module est de fournir des scripts scilab les plus courts possibles, mais sans expliquer ligne par ligne ce qui est demandé à scilab. C’est pour cela qu’il est souhaitable de parcourir au moins une fois l’ensemble des outils précédant celui qui doit être utilisé, en ayant assimilé et “déchiffré” les scripts associés.

Les figures sont presque toutes en niveaux de gris pour que les daltoniens ne soient pas pénalisés. Lorsque les couleurs sont utilisées, leur nom est pris dans la liste des couleurs disponible dans l’aide de scilab dans “color_list”.

La version de scilab utilisée est la 6.0.1.

Les scripts python sont exécutés dans l’environnement “spyder”. Ils ne sont présentés que pour information. Ils ne servent en rien à l’apprentissage des figures dans scilab. Ils ont servi à l’enregistrement des films. Ils peuvent être utiles aux personnes qui souhaiteraient automatiser des présentations avec scilab.

Les figures 2D

La “figure” et son “axe”

La fonction de base en 2D

La fonction de base est plot2d(x,y).

x est un vecteur (ligne ou colonne), y est un vecteur de même taille que x.

La fonction crée une fenêtre si nécessaire ou active le système d’axe actuel, puis trace y en fonction de x.

xdel(winsid()); //Ferme toutes les fenêtres de figures
f=scf(1); //Crée une figure de "handle" f (set current figure)
x=linspace(-%pi,%pi,50);
y=sin(x);
plot2d(x,y);

Les propriétés de base de la figure

Une figure est définie par sa position et sa taille, ses menus, sa barre d’outils, et sa barre d’information.

La visibilité de toutes ces entités est gérée par des propriétés de la figure.

La position et la taille

Il est possible d’afficher la figure sur un écran secondaire. Il faut entrer des valeurs négatives pour l’écran situé à gauche de l’écran principal.

Les valeurs sont exprimées à partir du coin haut gauche de l’écran principal et en pixels

xdel(winsid());
x=linspace(-%pi,%pi,50);
y=sin(x);
plot2d(x,y);
f=gcf();
// la position (en pixels)
f.figure_position=[10 10]; // dans le coin gauche de l'écran ; une valeur négative de la première variable positionne la figure sur un écran situé à gauche de l'écran principal
// la taille (ici plus haute que large)
f.figure_size=[400,600];

Le nom dans la barre de titre

Les caractères affichés dans la barre de titre sont définis par le nom de la figure.

Les caractères spéciaux sont obtenus par leur code ASCII.

xdel(winsid());
x=linspace(-%pi,%pi,50);
y=sin(x);
plot2d(x,y);
f=gcf();
f.figure_position=[10 10];
f.figure_size=[400,600];
f.resize='off'; // l'utilisateur ne peut pas modifier la taille de la figure à l'aide de la souris
f.figure_name='Caractères '+ ascii(34) + 'ASCII' + ascii(34); //latex n'est pas possible dans cette propriété

Les barres de menu, outils et information

Il existe 3 autres barres que l’on peut afficher ou cacher en modifiant une propriété de type “visible”.

La visibilité de chaque barre est gérée par une propriété de la figure :

  • f.menubar_visible
  • f.toolbar_visible
  • f.infobar_visible

xdel(winsid());
x=linspace(-%pi,%pi,50);
y=sin(x);
plot2d(x,y);
f=gcf();
f.figure_position=[10 10];
f.figure_size=[400,600];
f.resize='off';
f.figure_name='Caractères '+ ascii(34) + 'ASCII' + ascii(34);
f.menubar_visible='off';// les menus peuvent être cachés (Fichier, Outils, Edition)
f.toolbar_visible='off'; // les outils (pivoter, zoom, ...) peuvent être cachés
f.infobar_visible='off'; // Les informations peuvent être cachées (partie basse de la figure)

Les propriétés de base des axes

Le systèmes d’axes est un enfant de la figure

f=gcf() ; // get current figure
ax=f.children(i) ; // i est le numéro de l'enfant. Le dernier créé porte le numéro 1.

La localisation

La position d’un axe est définie par rapport à l’autre axe

Pour l’axe horizontal, la position peut être “origin”, “bottom” (par défaut), “top”, et “middle”

Pour l’axe vertical, la position peut être “origin”, “left” (par défaut), “right”, et “middle”

xdel(winsid());
x=linspace(-%pi,%pi,50);
y=sin(x);
plot2d(x,y);
f=gcf();
f.figure_position=[10 10];
f.figure_size=[400,600];
ax=f.children(1);
ax.x_location='origin'; // par défaut "bottom", peut être aussi "top" et "middle"
ax.y_location='origin'; // par défaut "left", peut être aussi "right" et "middle"

Le sens et la visibilité

Il ne faut pas oublier que par défaut le système d’axes comporte 3 axes.

xdel(winsid());
x=linspace(-%pi,%pi,50);
y=sin(x);
plot2d(x,y);
f=gcf();
f.figure_position=[10 10];
f.figure_size=[400,600];
ax=f.children(1);
ax.x_location='origin';
ax.y_location='origin';
ax.axes_visible=['on', 'off', 'off'];
ax.axes_reverse=['on', 'off', 'off'];

La grille

L’apparence de la grille est gérée par des propriétés du système d’axes

Chaque axe de la grille possède ses propres caractéristiques.

La visibilité

La propriété de l’axe est “grid”.

Elle est gérée par une matrice : ax.grid=[x,y]

-x et y prennent la valeur 0 (trait tracé) ou -1 (pas de trait).

xdel(winsid());
x=linspace(-%pi,%pi,50);
y=sin(x);
plot2d(x,y);
f=gcf();
f.figure_position=[10 10];
f.figure_size=[400,600];
ax=f.children(1);
ax.x_location='origin';
ax.y_location='origin';
ax.grid=[-1,0] //-1 ne trace pas la grille sur cet axe

Les types de traits

La propriété correspondante est grid_style

Le type de trait se retrouvera pour la représentation des courbes.

Voir les types de trait ci-dessous.

xdel(winsid());
x=linspace(-%pi,%pi,50);
y=sin(x);
plot2d(x,y);
f=gcf();
f.figure_position=[10 10];
f.figure_size=[400,600];
ax=f.children(1);
ax.x_location='origin';
ax.y_location='origin';
ax.grid=[0,0]
ax.grid_thickness=[1,2];
ax.grid_style=[1,4]; // valeurs entières de 1 à 10

Les limites des axes

Il est nécessaire de gérer 2 propriétés

Il faut définir les “data_bounds” et “tight_limits”

xdel(winsid());
x=linspace(-%pi,%pi,100);
y=sin(x);
plot2d(x,y);
f=gcf();
f.toolbar_visible='off';
f.menubar_visible='off';
f.infobar_visible='off';
f.figure_name='Limites du tracé';
f.figure_position=[10 10];
ax=f.children(1);
ax.font_size=2;
ax.data_bounds=[x(1) -1; x($) 1]; // [x_min y_min ; x_max y_max]
ax.tight_limits=['on' 'on' 'on'];
ax.x_location='origin';

Les graduations (gestion des axes du système d’axes)

Les “ticks” sont modifiables par des propriétés d’axes

Par exemple ;

ax.autoticks=['on' ou 'off' 'on' ou 'off' 'on' ou 'off' ] ;
ax.x_ticks=[tlist_x] ; ax.y_ticks=[tlist_y] ;

Il est possible d’utiliser des expressions Latex, mais il faut gérer la taille de police pour l’adapter à la police générale du tracé.

Latex offre le choix entre “large”, “Large”, “LARGE”, “huge”, et “Huge”.

Les sub-ticks sont gérés par une matrice.

En utilisant uniquement les fonctions de base le résultat n’est pas toujours satisfaisant.

La position des informations n’est pas finement modulable.

Ici l’abscisse -pi n’est pas visible correctement.

xdel(winsid());
x=linspace(-%pi,%pi,100);
y=sin(x);
plot2d(x,y);
f=gcf();
f.toolbar_visible='off';
f.menubar_visible='off';
f.infobar_visible='off';
f.figure_name='Les graduations';
f.figure_position=[10 10];
ax=f.children(1);
ax.font_size=2; // taille de la police de caractères
ax.data_bounds=[x(1) -1; x($) 1];
ax.tight_limits=['on' 'on' 'on'];
ax.x_location='origin';
ax.y_location='origin';
ax.auto_ticks=['off' 'on' 'on']; // les "ticks" ne sont plus gérés automatiquement sur l'axe x
x_t_location=[-%pi 0 %pi];
x_t_label=['$\huge{-\pi}$' '$\Large{0}$' '$\huge{\pi}$']; // Notation Latex, de même taille que x_t_location
ticks_x = tlist(["ticks","locations","labels"], x_t_location, x_t_label); // ceci est une tlist
ax.x_ticks=ticks_x;
ax.sub_ticks=[1 3]; // 1 sub_tick sur x, 3 sub_ticks sur y

Il est possible de remplacer un “tick” en utilisant la fonction xstring

Il faut “effacer” le tick créé automatiquement.

On définit ensuite le texte de remplacement en utilisant éventuellement une syntaxe Latex.

xdel(winsid());
x=linspace(-%pi,%pi,100);
y=sin(x);
plot2d(x,y);
f=gcf();
f.toolbar_visible='off';
f.menubar_visible='off';
f.infobar_visible='off';
f.figure_name='Un tick manuel';
f.figure_position=[10 10];
ax=f.children(1);
ax.font_size=2;
ax.data_bounds=[x(1) -1; x($) 1];
ax.tight_limits=['on' 'on' 'on'];
ax.x_location='origin';
ax.y_location='origin';
ax.auto_ticks=['off' 'on' 'on'];
x_t_location=[-%pi 0 %pi];
x_t_label=['' '0' '$\huge{\pi}$']; // Notation Latex, on définit un texte vide pour le premier tick
ticks_x = tlist(["ticks","locations","labels"], x_t_location, x_t_label);
ax.x_ticks=ticks_x;
ax.sub_ticks=[1 3];
xstring(-%pi,0,'$\huge{-\pi}$');
// si la position ne convient pas, on gère la position "manuellement"
text=gce(); // get current entity
text.data=[-3.3,0]; // gére la position en (x,y)

Les graduations sur un système d’axes personnel

On utilise ici la fonction “drawaxis”

ax=drawaxis(x,y,c) ;

x et y donnent la position de l’axes

c donne le côté des graduations sur l’axes :

  • dir=’u’ (“up”) ou dir=’d’ (“down”) sur un axe horizontal
  • dir=’l’ (“left”) ou dir=’r’ (“right”) sur un axes vertical

Il ne faut pas oublier de ne pas tracer les axes de base.

On note également que “tics” ne s’écrit pas avec un “k” pour un axe défini avec “drawaxis”

xdel(winsid());
x=linspace(-%pi,%pi,100);
y=sin(x);
plot2d(x,y,1,'020'); //le "1" correspond au type de ligne (voir l'aide sur la grille)
// 020 correpond à l'effacement des axes avec un tracé entre les limites de x et de y
f=gcf();
f.toolbar_visible='off';
f.menubar_visible='off';
f.infobar_visible='off';
f.figure_name='Les axes personnalisés';
f.figure_position=[10 10];
ax1=drawaxis(x=[-%pi 0 %pi] ,y=0,dir='u') ;
ax1.tics_labels=['$\huge{-\pi}$' ' ' '$\huge{\pi}$'];
ax2=drawaxis(x=0 ,y=[-1:0.2:0],dir='r'); // partie sous l'axe des x
y_c=[-1 -0.8 -0.6 -0.4 -0.2 0 ];
ax2.ytics_coord = y_c; // On n'utilise pas de tlist
y_l=[];
for i=1:5
y_l=[y_l sprintf('%1.1f',y_c(i))];
end
y_l=[y_l ' '];
ax2.tics_labels=y_l;
ax2.labels_font_size = 2;
ax3=drawaxis(x=0 ,y=[0:0.2:1],dir='l'); // partie au-dessus de l'axe x
ax3.format_n='%1.1f'; // plus rapide si le "0" est nécessaire
ax3.sub_tics=4; // pour en avoir 3 (4 intervalles)
ax3.labels_font_size = 2;

Les labels et le titre

Les propriétés des axes permettent d’ajouter rapidement de l’information, mais sans pouvoir affiner les positions

Un des avantages est de pouvoir connaître la largeur du texte que l’on souhaite utiliser.

On note que le titre se place dans une zone non accessible par la fonction xstring.

xdel(winsid());
x=linspace(-%pi,%pi,100);
y=1+sin(x);
plot2d(x,y);
f=gcf();
f.toolbar_visible='off';
f.menubar_visible='off';
f.infobar_visible='off';
f.figure_name='Le titre automatique';
f.figure_position=[10 10];
ax=f.children(1);
ax.font_size=2;
ax.data_bounds=[x(1) 0; x($) 2];
ax.tight_limits=['on' 'on' 'on'];
ax.x_location='origin';
ax.y_location='origin';
ax.auto_ticks=['off' 'on' 'on'];
x_t_location=[-%pi 0 %pi];
x_t_label=['$\huge{-\pi}$' '$\Large{0}$' '$\huge{\pi}$'];
ticks_x = tlist(["ticks","locations","labels"], x_t_location, x_t_label);
ax.x_ticks=ticks_x;
ax.sub_ticks=[1 3];
ax.title.text=['Mon titre' ; 'sur plusieurs lignes']; // une forme matricielle permet d'écrire sur plusieurs lignes
ax.title.font_size=3;
// pas de possibilité de tracé un encadrement, ni de centrer le texte
// par contre le texte est au_dessus du tracé là où il n'est pas possible d'utiliser la fonction xstring
ax.x_label.text='Label x';
ax.x_label.font_size=3;
temp=ax.x_label.position;
ax.x_label.position=[ax.data_bounds(2,1)+2*temp(1) temp(2)];
// max(x) -2*(1/2 largeur du texte)
//le texte étant centré par défaut sur 0 ici, temp(1) est négatif et correspond à la demi largeur du texte
y_l='$\large{y=\sin(t)+1}$';
ax.y_label.text=['Label ' y_l];
ax.y_label.font_size=3;
temp=ax.y_label.position;
y_l=ax.data_bounds(2,2)-2*((ax.data_bounds(2,2)+ax.data_bounds(1,2))/2-temp(2));
// max(y)-2*(moyenne(y)-position_inférieure) parce que y est positif
ax.y_label.position=[temp(1) y_l];

Il est possible d’utiliser la fonction xstring pour gérer la position et le centrage des textes

la fonction est xstring(x,y,a,b)

  • x et y donnent la localisation du texte
  • a donne l’orientation du texte dans le sens horaire en degrés
  • b indique si une boîte est tracée autour du texte

xdel(winsid());
x=linspace(-%pi,2*%pi,100);
y=1+sin(x); // varie donc de 0 à 2
plot2d(x,y);
f=gcf();
f.toolbar_visible='off';
f.menubar_visible='off';
f.infobar_visible='off';
f.figure_name='Le titre manuel';
f.figure_position=[10 10];
f.figure_size=[600 400];
ax=f.children(1);
ax.font_size=2;
min_y=-0.5;
ax.data_bounds=[x(1) min_y; x($) 3]; // le maximum de y est plus petit que la limite donnée ici
// pour laisser de la place au-dessus de l'axe pour le titre
ax.tight_limits=['on' 'on' 'on'];
ax.x_location='origin';
ax.y_location='origin';
ax.axes_visible = ['on' 'off' 'off']; // l'axe vertical par défaut n'est pas tracé
ax.auto_ticks=['off' 'on' 'on']; // les ticks sont définis par programmation
x_t_location=[-%pi 0 %pi 2*%pi];
x_t_label=['$\huge{-\pi}$' '$\Large{0}$' '$\huge{\pi}$' '$\Large{2}\huge{\pi}$'];
ticks_x = tlist(["ticks","locations","labels"], x_t_location, x_t_label);
ax.x_ticks=ticks_x;
ax_vert=drawaxis(x=0 ,y=[0:0.5:2],dir='l'); // on impose un axe vertical limité ce qui laisse de la place pour le titre
ax_vert.format_n='%1.1f';
ax_vert.sub_tics=2;
// définition du titre ---------------------------------------------------------------------
t_pos_x=(ax.data_bounds(1,1)+ax.data_bounds(2,1))/2; // le milieu de l'axe horizontal
t_pos_y=2.5; // A ajuster en fonction de la taille de la figure
xstring(t_pos_x,t_pos_y,['Mon titre'; 'sur plusieurs lignes'],0,1);
title=gce();
title.font_size=3;
title.alignment='center'; // position du texte dans la boîte
title.text_box_mode='centered'; // position de la boîte par rapport au point d'accroche
// fin de définition du titre ---------------------------------------------------------------
text_x='Angle (rd)';
xstring(1,1,text_x,0,0); // la position est gérée ensuite
x_label=gce();
font_size=3;
x_label.font_size=font_size;
x_label.data=[4.5 min_y] ; donne la position de x_label
text_y_1='Label ';
text_y_2='$\large{y=\sin(t)+1}$';
text_y=[text_y_1 text_y_2]
xstring(0,1,text_y,0,0);
y_label=gce();
y_label.font_size=font_size;
y_label.font_angle=-90; // inclinaison du texte, ici rotation anti-horaire
y_label.data=[-0.5 0] ; // position de y_label

La place du système d’axes dans la figure

Les marges sont une propriété du système d’axes

La fonction est ax.margins=[m_1, m_2, m_3,m_4]

  • m_1 est la marge de gauche, m_2 la marge de droite
  • m_3 est la marge supérieure, m_4 la marge inférieure

Les valeurs par défaut sont [0.125 0.125 0.125 0.125]

Le script (sans les indications de placement)

xdel(winsid());
x=linspace(-2,2,100);
y=x.^3;
plot2d(x,y);
f=gcf();
f.toolbar_visible='off';
f.menubar_visible='off';
f.infobar_visible='off';
f.figure_name='Les marges';
f.figure_position=[10 10];
f.figure_size=[600 400];
ax=f.children(1);
ax.font_size=2;
ax.margins=[0.1 0.2 0.4 0.15];
ax.data_bounds=[x(1) -10; x($) 10];
ax.tight_limits=['on' 'on' 'on'];
ax.x_location='origin';
ax.y_location='origin';
xstring(1,5,'Texte coupé par les limites');
text=gce();
text.font_size=3;
xstring(1,1,'Texte coupé par les limites',-90);
text=gce();
text.font_size=3;

Les labels et le titre positionnés par calcul

Les informations sont positionnées dans un second système d’axes

Il faut donc utiliser la fonction newaxes()

On rend le second système d’axes transparent en gérant sa propriété “filled”.

xdel(winsid());
x=linspace(-2,3,100);
y=x.^3;
plot2d(x,y);
f=gcf();
f.toolbar_visible='off';
f.menubar_visible='off';
f.infobar_visible='off';
f.figure_name='Les labels positionnés par calcul';
f.figure_position=[10 10];
figure_w=800;
figure_h=400;
f.figure_size=[figure_w figure_h];
ax=f.children(1);
margins=[0.10 0.10 0.25 0.10]
ax.margins=margins
y_min=-10; // on note que ceci est inférieur à -8
y_max=30; // on note que ceci est supérieur à 27
ax.data_bounds=[x(1) y_min; x($) y_max]; // les ticks automatiques seront corrects de -10 à 30
ax.tight_limits=['on' 'on' 'on'];
ax.x_location='origin';
ax.y_location='origin';
font_size=4;
ax.font_size=font_size;
ax1=newaxes(); // création du second système d'axes
ax1.margins=[0 0 0 0]; // celui-ci prend l'intégralité de la figure
ax1.axes_visible=['off' 'off' 'off'] ; // Les axes sont cachés, par défaut un système d'axes possède comme limites 0 et 1 sur les deux axes
ax1.filled='off' ; // le fond est transparent
label_x_text='Position (m)'
xstring(0.02,0.5,label_x_text)
label_x=gce();
font_style=label_x.font_style;
label_x.font_size=font_size;
rect_x=xstringl(0,0,label_x_text,font_style,font_size); // dimensions de la boîte entourant le texte
// rect_x(3) donne la longueur, rect_x(4) donne la hauteur
pos_max_x=1-margins(2) ; soit ici 0.9.
label_x_x=pos_max_x-rect_x(3) ; // le texte se terminera bien en pos_max_x
// position au-dessus de l'axe sachant qu'il passe par l'origine
label_x_y=margins(4)+(1-(margins(3)+margins(4)))/(1+y_max/abs(y_min));
label_x.data=[label_x_x,label_x_y]
label_y_text='$\Huge{y=x^{3}}$'
xstring(0.02,0.5,label_y_text)
label_y=gce();
rect_y=xstringl(0,0,label_y_text);
label_y.font_angle=-90;
label_y_x=margins(1)+(1-(margins(1)+margins(2)))/(1+x($)/abs(x(1)))-0.32/(figure_w/100);
// 0,32 est arbitraire mais semble convenir à beaucoup de tailles de fenêtres
label_y_y=(1-margins(3))-rect_y(3)*figure_w/figure_h;
label_y.data=[label_y_x,label_y_y];
ax1.data_bounds=[0 0; 1 1];
ax1.tight_limits=['on' 'on' 'on'];
titre_texte=['Le titre';'sur plusieurs lignes']
font_size_titre=font_size+1;
rect_titre=xstringl(0,0,titre_texte,font_style,font_size_titre);
titre_x=0.5; // l'axe x de ax1 varie bien de 0 à 1 et donc ici le texte sera centré sur l'axe x
titre_y=1-rect_titre(4)/2;
xstring(titre_x,titre_y,titre_texte)
titre=gce();
titre.alignment='center';
titre.text_box_mode='centered';
titre.font_size=font_size_titre;
titre.box='on'; // il est bien possible d'entourer le texte

Un axe logarithmique

Il est possible d’utiliser automatiquement un axe logarithmique, ou d’en définir un en utilisant la commande xarrows

La second solution offre plus de souplesse dans la représentation d’un axe.

La propriété log_flags d’un système d’axes permet de choisir le type d’axe

La fonction est ax.log_flags=’abc’ ;

  • a, b, et c (respectivement axe x, axe y, axe z) peuvent prendre la valeur ‘l’ (pour logarithmique) ou ‘n’ pour linéaire

xdel(winsid());
x=logspace(-2,2,100);
y=log(x);
f1=scf(1);
f1.figure_size=[600,600];
f1.resize='off';
f1.toolbar_visible='off';
f1.menubar_visible='off';
f1.infobar_visible='off';
plot2d(x,y);
ax1=f1.children(1);
ax1.axes_visible=['on', 'on', 'off'];
ax1.axes_reverse=['off', 'off', 'off'];
ax1.x_location='origin';
ax1.y_location='origin'; // il n'y a pas de "0" sur un axe logarithmique, l'axe est ici placé en 10^0 (soit 1)
ax1.log_flags='lnn';
f1.figure_name='Axes à l' + ascii(39)+'origine et log_flags à lnn';

Un axe logarithmique personnalisé est obtenu avec la fonction xarrows.

La fonction permet de dessiner plusieurs flèches en une seule instruction :

xarrows([v1_x v2_x],[v1_y v2_y], taille_embout, couleur)

– v_x et v_y sont les coordonnées dans le système d’axe courant

– la taille de l’embout (à gérer en fonction des données à représenter et de la taille de fenêtre)

– couleur s’exprime en fonction de la carte de couleur de la figure

Il est ensuite possible de définir l’épaisseur des traits.

xdel(winsid());
x=logspace(-2,2,100);
y=log(x);
f1=scf(1);
f1.figure_size=[600,600];
f1.resize='off';
f1.toolbar_visible='off';
f1.menubar_visible='off';
f1.infobar_visible='off';
f1.color_map=graycolormap(10); // la carte de couleur est définie ici en niveaux de gris
ax1.log_flags='nnn';
plot2d(log(x),y); // on garde les échelles linéaires, il faut donc utiliser le logarithme de x
ax1=f1.children(1);
ax1.axes_visible=['off', 'on', 'off'];
ax1.data_bounds=[log(0.007) -5 ; log(130) 5]; // la limite inférieure est plus petite que log(0.01) pour avoir de la place pour écrire à gauche
ax1.tight_limits=['on' 'on' 'on'];
ax1.x_location='origin';
ax1.y_location='origin'; // on place bien ici l'axe en "0"
f1.figure_name='Axe logarithmique personnalisé';
tics_x=[0.01 0.05 0.1 5 10 50 100];
coord_tics_x=log(tics_x);
coord_tics_y=[2 2.2]; // pour définir la taille des ticks et leur position par rapport à l'axe (ici au-dessus)
xarrows([coord_tics_x(1); coord_tics_x($)],[coord_tics_y(1); coord_tics_y(1)] ,0,0) ; // dessine une droite représentant l'axe (taille d'embout nul), et noir (couleur "0")
seg=ax1.children(1); // il s'agit de la dernière entité de ce type à avoir été générée
seg.thickness=2; // modifie l'épaisseur du trait d'axe (ax1.thickness gère l'épaisseur du trait d'axe, des ticks, et des sub-ticks
// on trace ici les tics principaux
xarrows([coord_tics_x(1:2:$); coord_tics_x(1:2:$)],[coord_tics_y(1)*ones(coord_tics_x(1:2:$)) ; coord_tics_y(2)*ones(coord_tics_x(1:2:$))],0,0);
// ici uniquement pour les valeurs 0.01 0.1 10 et 100 par (1 :2 :$)
segs=ax1.children(1);
segs.thickness=2; // c'est l'épaisseur du trait d'axe
// on trace ici les tics secondaires pour les valeurs 0.05 5 et 50
xarrows([coord_tics_x(2:2:$); coord_tics_x(2:2:$)],[coord_tics_y(1)*ones(coord_tics_x(2:2:$)) ; coord_tics_y(2)*ones(coord_tics_x(2:2:$))],0,0);
segs=ax1.children(1);
segs.thickness=0; // les sub_ticks n'ont pas la même épaisseur que le trait d'axe
segs.segs_color = [5,7,9]; // segs correspond à 3 entités qui ont toutes une couleur différente (de plus en plus claire)
// les valeurs sont alors affichées en une localisation calculée
text1='$\Large{10^{-2}}$';
rect1=xstringl(0.01,0,text1);
xstring(coord_tics_x(1)-rect1(3)/2,coord_tics_y(1)-1.1*rect1(4),text1);
text2='$\Large{10^{-1}}$';
rect2=xstringl(coord_tics_x(3),0,text2);
xstring(coord_tics_x(3)-rect2(3)/2,coord_tics_y(1)-1.1*rect2(4),text2);
text3='$\Large{10}$';
rect3=xstringl(coord_tics_x(5),0,text3);
xstring(coord_tics_x(5)-rect3(3)/2,coord_tics_y(1)-1.1*rect3(4),text3);
text4='$\Large{100}$';
rect4=xstringl(coord_tics_x($),0,text4);
xstring(coord_tics_x($)-rect4(3)/2,coord_tics_y(1)-1.1*rect4(4),text4);

Scilab ne fait pas toujours ce que nous voudrions qu’il fasse

Même si les propriétés “data_bounds” et “tight_limits” sont respectées, les ticks ne sont pas toujours au même endroit.

La localisation dépend à la fois de la taille de la figure et des marges du système d’axes.

Le script ci-dessous trace une droite partant de (-5,-5) et arrivant à (6,6) pour 3 figures comportant chacune 2 systèmes d’axes.

Figure 1 :

  • axe 1 : ticks -5 0 et 5 sur les 2 axes
  • axe 2 : ticks -4 :2 :6 sur les 2 axes

Figure 2 :

  • axe 1 : ticks -4 :2 :6 sur l’axe horizontal ; -5, 0 et 5 sur l’axe vertical
  • axe 2 : ticks -5 :1 :6 sur l’axe horizontal ; -4 :2 :6 sur l’axe vertical

Figure 3 :

  • axe 1 : ticks -4 :2 :6 sur l’axe horizontal ; -5 :1 :6 sur l’axe vertical
  • axe 2 : ticks -5 :1 :6 sur l’axe horizontal ; -5 :1 :6 sur l’axe vertical

xdel(winsid());
margins=[0.1 0.6 0.125 0.125; 0.45 0.05 0.03 0.03 ];
size_figure=[300 300; 600 300; 600 600];
position=[10 10; 10 234; 596 10];
for i=1:3
f=scf(i);
f.figure_position=position(i,:);
plot2d([-5 6],[-5 6]);
f.figure_size=size_figure(i,:);
f.resize='off';
f.toolbar_visible='off';
f.menubar_visible='off';
f.infobar_visible='off';
f.figure_name='Figure ' + string(i);
ax1=f.children(1);
ax1.axes_visible=['on', 'on', 'off'];
ax1.axes_reverse=['off', 'off', 'off'];
ax1.x_location='origin';
ax1.y_location='origin';
ax1.log_flags='nnn';
ax1.data_bounds=[-5 -5; 6 6];
ax1.tight_limits=['on' 'on' 'on'];
ax1.margins=margins(1,:);
ax2=newaxes();
ax2.margins=margins(2,:);
plot2d([-5 6],[-5 6]);
ax2.x_location='origin';
ax2.y_location='origin';
ax2.log_flags='nnn';
ax2.data_bounds=[-5 -5; 6 6];
ax2.tight_limits=['on' 'on' 'on'];
end

Il est possible d’imposer les ticks qui sont respectés pour toutes les tailles de fenêtre

On peut par exemple utiliser la fonction drawaxis.

Ceci permet notamment de gérer facilement la position des ticks ; par exemple lorsque les valeurs ne sont pas symétriques par rapport à l’origine comme ce qui est le cas volontairement ici.

xdel(winsid());
margins=[0.1 0.6 0.125 0.125; 0.45 0.05 0.03 0.03 ];
size_figure=[300 300; 600 300; 600 600];
position=[10 10; 10 234; 596 10]
for i=1:3
f=scf(i);
f.figure_position=position(i,:);
plot2d([-5 6],[-5 6]);
f.figure_size=size_figure(i,:);
f.resize='off';
f.toolbar_visible='off';
f.menubar_visible='off';
f.infobar_visible='off';
f.figure_name='Figure ' + string(i) ;
ax1=f.children(1);
ax1.axes_visible=['off', 'off', 'off'];
ax1.axes_reverse=['off', 'off', 'off'];
// limites extérieures aux min et max de x et de y
ax1.data_bounds=[-5.5 -5.5; 6.5 6.5];
ax1.tight_limits=['on' 'on' 'on'];
ax1.margins=margins(1,:)
tics=[-5 -3 -1 0 2 4 6];
// l'axe horizontal
ax1_1=drawaxis(x=tics ,y=0,dir='d');
ax1_1.sub_tics=1;
ax1_1.tics_labels=string(tics);
// l'axe vertical
ax1_2=drawaxis(x=0 ,y=tics,dir='l');
ax1_2.sub_tics=1;
ax1_2.tics_labels=string(tics);
// le second graphe
ax2=newaxes();
ax2.margins=margins(2,:);
plot2d([-5 6],[-5 6]);
ax2.axes_visible=['off', 'off', 'off'];
ax2.log_flags='nnn';
ax2.data_bounds=ax1.data_bounds;
ax2.tight_limits=['on' 'on' 'on'];
tics=[-5 -4 -3 -2 -1 0 1 2 3 4 5 6];
ax2_1=drawaxis(x=tics ,y=0,dir='d');
ax2_1.sub_tics=1;
ax2_1.tics_labels=string(tics);
ax2_2=drawaxis(x=0 ,y=tics,dir='l');
ax2_2.sub_tics=1;
ax2_2.tics_labels=string(tics);
end

Une représentation avec les échelles identiques sur les 2 axes

La propriété “isoview” d’un axe permet de gérer automatiquement la bonne proportion entre les axes

Si ax est un système d’axes, alors ax.isoview=’on’ permet d’avoir la même échelle sur les deux axes

clc
clear
xdel(winsid());
f=gcf();
f.toolbar_visible='off';
f.menubar_visible='off';
f.infobar_visible='off';
f.figure_name='Les échelles identiques';
f.figure_position=[10 10];
figure_w=400;
figure_h=600;
f.figure_size=[figure_w figure_h];
f.color_map=graycolormap(10)
ax=f.children(1);
x=linspace(-2,3,100);
y=x.^3/4;
plot2d(x,y)
margins=[0.1 0.1 0.1 0.10]
ax.margins=margins
ax.x_location='origin'
ax.y_location='origin'
y_min=-10;
y_max=30;
font_size=4;
label_x_text='Position (m)'
xstring(0.02,0.5,label_x_text)
label_x=gce();
font_style=label_x.font_style;
label_x.font_size=font_size;
rect_x=xstringl(0,0,label_x_text,font_style,font_size);
label_x_x=max(x)-rect_x(3)-0.5
label_x_y=-rect_x(4)-0.4;
label_x.data=[label_x_x,label_x_y]
label_y_text='$\Huge{y=x^{3}}$'
xstring(0.02,0.5,label_y_text)
label_y=gce();
rect_y=xstringl(0,0,label_y_text);
label_y.font_angle=-90;
label_y_x=-rect_y(4)
label_y_y=max(y)-rect_y(3);
label_y.data=[label_y_x,label_y_y];
ax.isoview='on'

Les polices de caractères

Il est possible de choir une police par son numéro ou par son nom.

Il est parfois nécessaire de gérer une erreur.

clc
clear
xdel(winsid());
f1=scf(1);
f1.figure_position=[10,10];
f1.figure_size=[600,600];
f1.resize='off';
f1.toolbar_visible='off';
f1.menubar_visible='off';
f1.infobar_visible='off';
ax1=f1.children(1);
ax1.axes_visible=['off', 'off', 'off'];
ax1.axes_reverse=['off', 'off', 'off'];
ax1.data_bounds=[-5 -5 ; 5 5];
ax1.tight_limits=['on' 'on' 'on'];
f1.figure_name='Différentes polices de caractères'
font_size=2;
xstring(-4.5,4.5,'Font_size='+string(font_size))
text_font=gce();
text_font.font_size=font_size;
text_font.font_style=4;
for font_style=0:5
xstring(-4.5,4-(font_style)*4.5/9,'Font_style '+ string(font_style))
text_font=gce();
text_font.font_size=font_size;
text_font.font_style=font_style;
end
for font_style=6:10
xstring(-2,4-(font_style-6)*4.5/9,'Font_style '+ string(font_style))
text_font=gce();
text_font.font_size=font_size;
text_font.font_style=font_style;
end
font_size=4;
xstring(-4.5,-1.5,'Font_size='+string(font_size))
text_font=gce();
text_font.font_size=font_size;
text_font.font_style=4;
for font_style=0:5
xstring(-4.5,-2-(font_style)*4.5/9,'Font_style '+ string(font_style))
text_font=gce();
text_font.font_size=font_size;
text_font.font_style=font_style;
end
for font_style=6:10
xstring(-1,-2-(font_style-6)*4.5/9,'Font_style '+ string(font_style))
text_font=gce();
text_font.font_size=font_size;
text_font.font_style=font_style;
end
if size(xlfont(),2)<11 then
n_font=xlfont('Century Schoolbook')
else
n_font=11;
end
xstring(1.1,4,'Century Schoolbook')
text_font=gce();
text_font.font_size=2;
ierr = execstr('text_font.font_style=n_font;','errcatch','n')
// La fonction text_font.font_style=n_font; renvoie une erreur mais s'applique tout de même
xstring(2,-2,'Century Schoolbook')
text_font=gce();
text_font.font_size=4;
ierr = execstr('text_font.font_style=n_font;','errcatch','n')

La gestion des textes

Le positionnement, la taille, l’inclinaison, la couleur du texte, l’entourage, la couleur du fond, sont gérés par des propriétés de l’entité créée.

Il n’est pas possible d’affecter une variable lors de la création de l’entité :

texte_entite = xstring(x,y,’texte’) ; renvoie une erreur : “xstring : Nombre erroné d’argument(s) de sortie : 0 attendu(s).”

Il est donc nécessaire de passer par la commande gce(); (“get current entity”) juste après avoir utilisé la fonction xstring.

Une croix est dessinée à chaque origine du texte écrit (position x,y donnée dans la commande xstring)

clc
clear
xdel(winsid());
f1=scf(1);
f1.figure_position=[20,20];
f1.figure_size=[600,600];
f1.resize='off';
f1.toolbar_visible='off';
f1.menubar_visible='off';
f1.infobar_visible='off';
f1.figure_name='Jouer avec les textes';
f1.color_map=graycolormap(10);
ax1=f1.children(1);
ax1.axes_visible=['on' 'on' 'off'];
ax1.grid=[0,0];
ax1.grid_style=[10,10]
temp=['A';'l';'i';'g';'n';'m';'e';'n';'t']
xstring(0.1,0.1,temp)
text_temp=gce();
text_temp.font_size=2;
text_temp.alignment='center';
plot2d([0.08 0.12],[0.1 0.1])
plot2d([0.1 0.1],[0.08 0.12])
xstring(0.2,0.1,temp)
text_temp=gce();
text_temp.font_size=2;
text_temp.alignment='left';
plot2d([0.18 0.22],[0.1 0.1])
plot2d([0.2 0.2],[0.08 0.12])
xstring(0.1,0.9,'Texte_1')
text_1=gce();
text_1.font_size=2;
plot2d([0.08 0.12],[0.9 0.9])
plot2d([0.1 0.1],[0.88 0.92])
xstring(0.2,0.8,'Texte_2')
text_2=gce();
text_2.font_size=2;
text_2.text_box_mode ='centered'
plot2d([0.18 0.22],[0.8 0.8])
plot2d([0.2 0.2],[0.78 0.82])
xstring(0.4,0.6,'Texte_3')
text_3=gce();
text_3.font_size=2;
text_3.font_angle=-90;
xstring(0.4,0.6,'Texte_4')
text_4=gce();
text_4.font_size=2;
text_4.font_angle=90;
plot2d([0.38 0.42],[0.6 0.6])
plot2d([0.4 0.4],[0.58 0.62])
xstring(0.5,0.5,'Texte_5')
text_5=gce();
text_5.font_size=2;
text_5.font_angle=45;
text_5.box='on';
plot2d([0.48 0.52],[0.5 0.5])
plot2d([0.5 0.5],[0.48 0.52])
for i=1:5
xstring(0.65,(i-1)/10+0.03,'Niveau de gris :' + string(i))
text_6=gce();
text_6.font_size=2;
text_6.font_angle=0;
text_6.box='on';
text_6.fill_mode='on';
text_6.background=i; // couleur du fond de la boîte entourant le texte
text_6.font_foreground=10; // couleur du texte
end
for i=6:10
xstring(0.65,(i-1)/10+0.03,'Niveau de gris :' + string(i))
text_6=gce();
text_6.font_size=2;
text_6.font_angle=0;
text_6.box='on';
text_6.fill_mode='on';
text_6.background=i;
text_6.font_foreground=0;
end
ax1.data_bounds=[0 0 ; 1 1];
ax1.tight_limits=['on' 'on' 'on'];

Les représentations 2D de données

Introduction

Au-delà de la représentation de courbes, les camemberts, les histogrammes, les champs de vecteurs, les champs de données, les courbes de niveaux, seront abordés.

Les marqueurs

Ils sont nécessaires pour distinguer facilement les courbes les unes des autres.

Ils possèdent des propriétés variées pour gérer leur aspect, leur nombre et leur position :

  • mark_mode=’on’; ou ‘off’ pour la visibilité des marqueurs
  • mark_style=i; pour i variant de 0 à 14 (voir la figure ci-dessous)
  • mark_size=i; pour i variant de 0 à 5 si mark_size_unit est “tabulated”
  • mark_stride=i; permet de gérer l’espacement entre 2 marqueurs successifs
  • mark_offset=i ; permet de gérer la position du premier marqueur.

clc
clear
xdel(winsid());
f=gcf();
f.toolbar_visible='off';
f.menubar_visible='off';
f.infobar_visible='off';
f.figure_name='Les marqueurs';
f.figure_position=[10 10];
figure_w=800;
figure_h=400;
f.figure_size=[figure_w figure_h];
ax=f.children(1);
ax.axes_visible=['on' 'on' 'off']
ax.font_size=2;
ax.x_location='top';
ax.y_location='origin';
for i=0:14
plot2d([0:10],(i)*ones([0:10]))
curve=ax.children(1).children(1) ; // la dernière courbe créée est bien le premier enfant du système d'axes
curve.mark_mode='on'
curve.mark_style=i;
curve.mark_size=2;
end
for i=0:7
plot2d([11:20],(i)*ones([11:20]))
curve=ax.children(1).children(1);
curve.mark_mode='on'
curve.mark_style=i;
curve.mark_size=2;
curve.mark_stride=2; // gère le nombre de marqueurs "oubliés", ici 1 sur 2
end
for i=8:14
plot2d([11:20],(i)*ones([11:20]))
curve=ax.children(1).children(1);
curve.mark_mode='on';
curve.mark_style=i;
curve.mark_size=2;
curve.mark_stride=3; // gère le nombre de marqueurs "oubliés", ici 1 sur 3
curve.mark_offset=1; // gère le décalage en début de courbe
end
ax.y_label.text='y=Mark_style';
ax.y_label.font_size=4;
ax.data_bounds=[-1 -1; 20 15];
ax.tight_limits=['on' 'on' 'on'];

Les marqueurs ont des options de couleur.

Les propriétés “mark_foreground”,” mark_background”, et “mark_size” permettent d’augmenter le nombre de marqueurs disponibles

L’exemple donné ici pour un marqueur est reproductible pour d’autres marqueurs.

clc
clear
xdel(winsid());
f=gcf();
f.toolbar_visible='off';
f.menubar_visible='off';
f.infobar_visible='off';
f.figure_name='La gestion des marqueurs';
f.figure_position=[10 10];
figure_w=400;
figure_h=400;
f.figure_size=[figure_w figure_h];
f.color_map=graycolormap(10)
ax=f.children(1);
x=linspace(-2,3,100);
y=x.^3/4;
plot2d(x,y)
margins=[0.1 0.1 0.1 0.10]
ax.margins=margins
ax.x_location='origin'
ax.y_location='origin'
curve=ax.children(1).children(1)
curve.mark_mode='on';
curve.mark_style=9;
curve.mark_offset=2;
curve.mark_stride=10;
curve.mark_foreground=0;
curve.mark_background=10;
plot2d(x,5-x.^2/3)
temp=gce();
curve_1=temp.children(1);
curve_1.mark_mode='on';
curve_1.mark_style=9;
curve_1.mark_offset=2;
curve_1.mark_stride=10;
curve_1.mark_foreground=7;
curve_1.mark_background=1; // 0 rend le marqueur "transparent"
curve_1.mark_size=2;

L’épaisseur, la couleur, le type de trait des courbes

Les fonctions les plus couramment utilisées sont l’épaisseur, la couleur et le type de trait.

Les propriétés sont respectivement :

  • thickness=n ; n est un entier en pixels (non entier pour un export vectoriel)
  • foreground=n ; n est un entier ici compris entre 0 et p pour une carte de couleur de la figure définie par f.color_map=graycolormap(p) ;

clc
clear
xdel(winsid());
f1=scf(1); // set current figure
f1.figure_size=[600,600];
f1.resize='off';
f1.toolbar_visible='off';
f1.menubar_visible='off';
f1.infobar_visible='off';
f1.figure_name='Aspect des courbes (épaiseur et couleur)';
f1.color_map=graycolormap(10);
t=linspace(0,2*%pi,100);
plot2d(t,1+1.4*sin(t))
ax=f1.children(1);
ax.margins=[0.1 0.1 0.1 0.1];
poly1=ax.children(1).children(1);
ax.data_bounds=[0 -0.5; 2*%pi 3]
ax.tight_limits=['on' 'on' 'on'];
poly1.thickness=6;
poly1.foreground=8
plot2d(t,1+1.4*sin(t)+0.2*(0.5-rand(t)))
poly2=ax.children(1).children(1);
poly2.thickness=1;
poly2.foreground=0;
for line_type=1:10
plot2d([4 6],((line_type-1)*0.2+1)*[1 1]);
poly3=ax.children(1).children(1);
poly3.line_style=line_type;
xstring(3.8,(line_type-1)*0.2+0.9,string(line_type))
end
for thickness=0:10
plot2d([1.1 1.6],(thickness*0.2-0.4)*[1 1]);
poly4=ax.children(1).children(1);
poly4.thickness=thickness;
xstring(0.9,(thickness*0.2-0.5),string(thickness))
end
for color_line=0:10
plot2d([1.7 2.2],(color_line*0.2-0.4)*[1 1]);
poly5=ax.children(1).children(1);
poly5.thickness=6;
poly5.foreground=color_line;
end
xstring(1.5,1.65,'Epaisseur',-90,1)
texte=gce();
texte.font_size=3;
xstring(2.2,1.65,'Couleur',-90)
texte=gce();
texte.font_size=3;
xstring(5,2.8,'Type')
texte=gce();
texte.font_size=3;

La limitation des courbes

La gestion de la limitation des courbes s’effectue par la combinaison des propriétés clip_state et clip_box

Il est nécessaire de définir les limites du système d’axes pour que la propriété clip_state=’off’ soit effective.

clc
clear
xdel(winsid());
f=gcf();
f.toolbar_visible='off';
f.menubar_visible='off';
f.infobar_visible='off';
f.figure_name='La limitation des courbes';
f.figure_position=[10 10];
figure_w=400;
figure_h=400;
f.figure_size=[figure_w figure_h];
f.color_map=graycolormap(10)
ax=f.children(1);
x=linspace(-2,3,100);
y=x.^3/4;
plot2d(x,y)
margins=[0.1 0.1 0.1 0.10]
ax.margins=margins
ax.x_location='origin'
ax.y_location='origin'
x1=linspace(-4,6,400);
plot2d(x1,2+x1.^2/10)
temp=gce();
curve_1=temp.children(1);
curve_1.clip_state='off';
plot2d(x1,5-x1.^2/3)
temp=gce();
curve_2=temp.children(1);
curve_2.clip_state='on'; // doit être associé à clip_box
curve_2.clip_box=[-1 6 3 2]
ax.data_bounds=[-2 -2 ;3 8]
ax.tight_limits=['on' 'on' 'on']

Les graphes cumulatifs

On utilise la possibilité de “remplir” une courbe pour créer des graphes cumulatifs.

Il faut bien faire attention à l’ordre des tracés. Le remplissage jusqu’à l’axe horizontal nécessite de “fermer” la courbe aux deux extrémités en y ajoutant une donnée.

Une légende créée automatiquement est présentée dans cet exemple.

clc
clear
xdel(winsid());
f1=scf(1);
f1.figure_size=[600,600];
f1.resize='off';
f1.toolbar_visible='off';
f1.menubar_visible='off';
f1.infobar_visible='off';
f1.figure_name='Cumul de données';
f1.color_map=graycolormap(10);
ax=f1.children(1);
ax.data_bounds=[2000 0;2016 20]
ax.tight_limits=['on' 'on' 'on']
an=[2000 2000 2002 2004 2006 2008 2010 2012 2014 2016 2016]; // 2000 est répété comme 2016
prod1=[0 5 6 4 8 6 4 7 8 5 0]; // on doit donc imposer une valeur nulle aux 2 extrémités.
prod2=[0 2 3 4 3 5 4 2 3 5 0];
prod3=[0 1 2 3 4 5 4 5 4 4 0]
plot2d(an,prod1+prod2+prod3);
poly1=ax.children(1).children(1)
poly1.fill_mode='on';
poly1.background=2
plot2d(an,prod1+prod2);// la différence avec "poly1" est bien la quantité "prod3"
poly2=ax.children(1).children(1)
poly2.fill_mode='on';
poly2.background=8
plot2d(an,prod1);
poly3=ax.children(1).children(1)
poly3.fill_mode='on';
poly3.background=5
legend(f1,'Produit 3', 'Produit 2', 'Produit 1', 2, %t ) // 2 correspond à "upper left". Les autres valeurs sont à voir dans l'aide de "legend" (propriété "pos")

Une légende peut être personnalisée

Comme pour n’importe quel texte, la légende peut être écrite avec du code Latex.

Un rectangle est créé dans la légende pour chaque courbe ; que ce soit autour du texte ou devant le texte (fonction “xrects”).

La légende est construite par concaténation de texte et de code latex.

xdel(winsid());
f1=scf(1);
f1.figure_size=[600,600];
f1.resize='off';
f1.toolbar_visible='off';
f1.menubar_visible='off';
f1.infobar_visible='off';
f1.figure_name='Cumul de données et légendes personnalisées';
f1.color_map=graycolormap(10);
ax=f1.children(1);
ax.data_bounds=[2000 0;2016 20]
ax.tight_limits=['on' 'on' 'on']
an=[2000 2000 2002 2004 2006 2008 2010 2012 2014 2016 2016];
prod1=[0 5 6 4 8 6 4 7 8 5 0];
prod2=[0 2 3 4 3 5 4 2 3 5 0];
prod3=[0 1 2 3 4 5 4 5 4 4 0];
// Il est posible d'inclure du texte Latex dans la légende
legend_1=['Produit ' '$x=1$']; // on note ici la façon de concaténer du texte et du code latex
legend_2=['Produit ' '$y=2$'];
legend_3=['Produit ' '$z=3$'];
couleur_1=9;
couleur_2=7;
couleur_3=5;
plot2d(an,prod1+prod2+prod3);
poly1=ax.children(1).children(1)
poly1.fill_mode='on';
poly1.background=couleur_1
plot2d(an,prod1+prod2);
poly1=ax.children(1).children(1)
poly1.fill_mode='on';
poly1.background=couleur_2
plot2d(an,prod1);
poly1=ax.children(1).children(1)
poly1.fill_mode='on';
poly1.background=couleur_3;
// les textes encadrés-----------------------------------------------------------------------
// le zéro est l'angle de la police qui permet de dessiner une boîte: le 1 en dernier
xstring(2001, 18.5,legend_1,0,1);
leg1=gce();
leg1.fill_mode='on';
leg1.background=couleur_3; // la propriété foreground gère la couleur de l'encadrement
leg1.font_foreground=10; // le texte sera blanc pour une lecture facile
xstring(2006, 18.5,legend_2,0,1);
leg2=gce();
leg2.fill_mode='on';
leg2.background=couleur_2;
xstring(2011, 18.5,legend_3,0,1);
leg3=gce();
leg3.fill_mode='on';
leg3.background=couleur_1;
// les textes ayant un symbole devant eux -------------------------------------------------
xstring(2001, 17,legend_1,0,0);
rect_4=xstringl(2001, 17,legend_1,0,0);
// recherche de la position et de la taille du texte de la légende
// rect_4(2) donne la position haute de la boîte entourant le texte
// rect_4(4) donne la hauteur de cette boîte
xrect([2000.5 rect_4(2),0.5,rect_4(4)]); // le symbole devant le texte
rect4=gce();
rect4.fill_mode='on';
rect4.background=couleur_3;
xstring(2006, 17,legend_2,0,0);
rect_5=xstringl(2006, 17,legend_2,0,0);
xrect([2005.5 rect_5(2),0.5,rect_5(4)]);
rect5=gce();
rect5.fill_mode='on';
rect5.background=couleur_2;
xstring(2011, 17,legend_3,0,0);
rect_6=xstringl(2011, 17,legend_3,0,0);
xrect([2010.5 rect_6(2),0.5,rect_6(4)]);
rect6=gce();
rect6.fill_mode='on';
rect6.background=couleur_1;

Comment mettre en avant une partie d’une courbe ?

La fonction intégrée “zoom_box” permet facilement de ne visualiser qu’une petite partie d’une courbe

S’il s’agit bien de dessiner un extrait d’une courbe, il faut créer un second système d’axes et de tracer la courbe dans ce système d’axe. Il est alors possible d’utiliser les mêmes valeurs à tracer.

La fonction xarc est utilisée pour entourer une zone d’intérêt.

clc
clear
xdel(winsid());
x=logspace(-2,2,200);
y=log(x)+0.2*rand(x);
f1=scf(1);
plot2d(x,y);
f1.figure_size=[600,600];
f1.resize='off';
f1.toolbar_visible='off';
f1.menubar_visible='off';
f1.infobar_visible='off';
f1.figure_name='Détails d'+ascii(39)+'une courbe'
ax1=f1.children(1);
ax1.x_location='origin';
ax1.y_location='origin';
ax1.log_flags='lnn';
ax1.data_bounds=[0.01 -5; 100 5];
ax1.tight_limits=['on' 'on' 'on'];
// encadrement de la zone d'intérêt
dim_rect_1=[5 2.5 5 1];
xrect(dim_rect_1)
// création d'un système d'axes secondaire
ax2=newaxes();
// localisé dans la partie haute (premier 0.6) à gauche (second 0.6)
ax2.margins=[0.2 0.6 0.2 0.6]
ax2.axes_visible=['on', 'on', 'off'];
plot2d(x,y) // on utilise bien les mêmes variables
ax2.zoom_box=[dim_rect_1(1) dim_rect_1(2)-dim_rect_1(4) dim_rect_1(1)+dim_rect_1(3) dim_rect_1(2)];
ax2.log_flags='lnn';
ax2.filled='off'; // transparent
ax2.sub_ticks=[4,8];
sca(ax1); // retour au système pincipal ("set current axes")
// encadrement du graphique
dim_rect_2=[0.01 4.3 0.49 3.8];
xrect(dim_rect_2);
// utilisation des dimensions précédentes pour tracer les traits de liaison graphique --> zone d'intérêt
plot2d([dim_rect_2(1)+dim_rect_2(3) dim_rect_1(1)],[dim_rect_2(2)-dim_rect_2(4) dim_rect_1(2)-dim_rect_1(4)]);
plot2d([dim_rect_2(1)+dim_rect_2(3) dim_rect_1(1)],[dim_rect_2(2) dim_rect_1(2)]);
// entourage de la zone d'intérêt par une ellipse
dim_arc=[30, 4 ,20, 0.4, 0,360*64]
xarc(dim_arc(1),dim_arc(2),dim_arc(3),dim_arc(4),dim_arc(5),dim_arc(6));
arc=gce();
arc.thickness=2;
// un nouveau système d'axes
ax3=newaxes();
// placé en bas (0.6) à droite (le 0.65)
ax3.margins=[0.6 0.2 0.65 0.2]
ax3.axes_visible=['on', 'on', 'off'];
plot2d(x,y);
ax3.zoom_box=[dim_arc(1) dim_arc(2)-dim_arc(4) dim_arc(1)+dim_arc(3) dim_arc(2)];
ax3.log_flags='lnn';
ax3.filled='off';
ax3.sub_ticks=[4,3];
sca(ax1);
dim_rect_2=[1.5 -1.7 70 3.3];
xrect(dim_rect_2);
// ici une flèche, le 4 donne la taille de la pointe en multiple de l'épaisseur du trait
xarrows((dim_arc(1)+dim_arc(3)/2)*[1 1],[dim_arc(2)-dim_arc(4) dim_rect_2(2)],4);

Une information locale est connue sous le nom de datatip

Les deux courbes ne sont pas tracées volontairement dans le même système d’axes pour voir la conséquence sur la gestion des datatips.

Une fois le script exécuté, il est possible de reproduire ce qui est montré dans le film.

Le film a été créé par programmation de scilab. Le script correspondant est donné en bas de page. Il a été enregistré avec le logiciel libre “OBS Studio”.

clc
clear
xdel(winsid());
x=linspace(-2,3,100);
y=x.^3;
plot2d(x,y($:-1:1));
f=gcf();
f.toolbar_visible='off';
f.menubar_visible='off';
f.infobar_visible='off';
f.figure_name='Les datatips';
f.figure_position=[10 10];
figure_w=800;
figure_h=400;
f.figure_size=[figure_w figure_h];
f.color_map=graycolormap(10)
ax=f.children(1);
ax.axes_visible=['off' 'off' 'off']
curve_1=ax.children(1).children(1)
curve_1.thickness=3;
curve_1.foreground=7;
margins=[0.10 0.10 0.25 0.10]
ax.margins=margins
y_min=-10;
y_max=30;
font_size=4;
ax1=newaxes();
ax1.margins=[0 0 0 0];
ax1.axes_visible=['off' 'off' 'off']
ax1.filled='off'
label_x_text='Position (m)'
xstring(0.02,0.5,label_x_text)
label_x=gce();
font_style=label_x.font_style;
label_x.font_size=font_size;
rect_x=xstringl(0,0,label_x_text,font_style,font_size);
pos_max_x=1-margins(2)
label_x_x=pos_max_x-rect_x(3)
label_x_y=margins(4)+(1-(margins(3)+margins(4)))/(1+y_max/abs(y_min));
label_x.data=[label_x_x,label_x_y]
label_y_text='$\Huge{y=x^{3}}$'
xstring(0.02,0.5,label_y_text)
label_y=gce();
rect_y=xstringl(0,0,label_y_text);
label_y.font_angle=-90;
label_y_x=margins(1)+(1-(margins(1)+margins(2)))/(1+x($)/abs(x(1)))-0.32/(figure_w/100);
label_y_y=(1-margins(3))-rect_y(3)*figure_w/figure_h;
label_y.data=[label_y_x,label_y_y];
xstring(0.02,0.5,'$\Huge{y=(1-x)^{3}}$')
label_y1=gce();
rect_y=xstringl(0,0,'$\Huge{y=(1-x)^{3}}$');
label_y1.font_angle=-90;
label_y_x=0.33;
label_y_y=0.375;
label_y1.data=[label_y_x,label_y_y];
label_y1.font_foreground=7
ax1.data_bounds=[0 0; 1 1];
ax1.tight_limits=['on' 'on' 'on'];
titre_texte=['On déplace le point avec la souris. Un clic droit efface le point'; 'Un clic gauche crée un point avec une marque par défaut']
font_size_titre=font_size+1;
rect_titre=xstringl(0,0,titre_texte,font_style,font_size_titre);
titre_x=0.5;
titre_y=1-rect_titre(4)/2;
xstring(titre_x,titre_y,titre_texte)
titre=gce();
titre.alignment='center';
titre.text_box_mode='centered';
titre.font_size=font_size_titre;
titre.box='on';
ax2=newaxes();
ax2.margins=margins
ax2.data_bounds=[x(1) y_min; x($) y_max];
ax2.tight_limits=['on' 'on' 'on'];
ax2.x_location='origin';
ax2.y_location='origin';
ax2.filled='off'
ax2.font_size=font_size;
plot2d(x,y);
curve=ax2.children(1).children(1);
curve.thickness=2;
curve.foreground=0;
curve.datatip_display_mode='mouseover';
curve_1.datatip_display_mode='mouseover';
datatipToggle()
temp=size(curve.data,1)
temp_1=size(curve_1.data,1)
datatip_1=datatipCreate(curve,temp*0.75+1)
datatip_1_1=datatipCreate(curve_1,temp*0.85+1)
function str=datatip_display(h);
h.auto_orientation='off';
h.orientation=4;
pt = h.data;
str1=msprintf('X: %0.4g', pt(1));
str2=msprintf('Y: %0.4g', pt(2));
str=[str1 ; str2];
endfunction;
datatipSetDisplay(curve,datatip_display);
datatipSetDisplay(curve_1,datatip_display);
datatipSetDisplay(datatip_1,datatip_display);
datatipSetDisplay(datatip_1_1,datatip_display);
datatip_2=datatipCreate(curve,temp*0.2+1)
datatip_2_1=datatipCreate(curve_1,temp_1*0.2+1)
datatipSetDisplay(datatip_2,datatip_display);
datatipSetDisplay(datatip_2_1,datatip_display);
datatip_2.mark_style=0;
datatip_2_1.mark_style=1;
datatip_1.mark_style=10;
datatip_1_1.mark_style=2;