Graphique Matlab [Résolu/Fermé]

- - Dernière réponse : Fee Fay
Messages postés
639
Date d'inscription
vendredi 17 octobre 2008
Statut
Membre
Dernière intervention
31 mai 2009
- 29 mars 2009 à 16:20
Bonjour,

Je dois tracer avec le logiciel matlab une fonction qui représente le trajet d'un rayon lumineux grâce à plusieurs formules qui font intervenir La Température, la hauteur, l'angle avec lequel arrive le rayon...
J'ai réussi a créé cette fonction et j'obtiens un graph qui est (selon moi) correct.
Maintenant je dois afficher plusieurs fonctions sur un même graph en faisant varier l'angle initial ( entre -1° et 0.1°)

J'ai essayé d'utiliser la commande
For i0=-1:0.1:0.1;
fonction(...);
plot(x,z);
end

Mais cela ne me donne que la fonction du dernier angle càd quand i0 est égal à 0.1.

Si quelqu'un pouvait me conseiller/guider, ça serait vraiment très gentil de sa part.
Afficher la suite 

11 réponses

Meilleure réponse
Messages postés
639
Date d'inscription
vendredi 17 octobre 2008
Statut
Membre
Dernière intervention
31 mai 2009
373
10
Merci
Bonsoir mon ami !

Tu as juste à ajouter la commande hold on avant ta boucle.
Si tu comptes ensuite relancer ton programme ou tracer d'autres courbes sur une autre figure, utilise la commande hold off avant, sinon tu auras les nouvelles courbes par-dessus celles de la figure obtenue par la boucle.
Finalement, pour résumer, fais quelque chose de ce genre :
hold on;
for i0=-1:0.1:0.1
fonction(...);
plot(x,z);
end
hold off;
Je te souhaite une bien bonne soirée !

Dire « Merci » 10

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

CCM 71199 internautes nous ont dit merci ce mois-ci

Messages postés
639
Date d'inscription
vendredi 17 octobre 2008
Statut
Membre
Dernière intervention
31 mai 2009
373
2
Merci
Il n'y a pas de quoi mon ami ! ;-)
Je ne sais pas trop comment sont organisées tes données mais je pense qu'ensuite tu peux faire ce dont tu me parles par indexation logique.

Comme tu débutes sous Matlab, je vais essayer de détailler au mieux mon propos.

Imaginons que tu aies par exemple un vecteur v=[2;-3;4;6;-1;0;3;5];.
Tu as la possibilité de faire appel aux éléments de ce vecteur par l'indexation habituelle, j'entends par-là v(1), v(2), etc...
Mais tu peux aussi accéder aux éléments de ce vecteur par indexation logique, à l'aide d'un vecteur de type booléen (appelons le z) de même taille que v.
z est donc composé de 0 et de 1. Un 0 dans z signifiera que tu ne prendras pas l'élément de v à la même position que le 0 dans z. Au contraire, un 1 signifiera que tu le prendras.
Illustrons ce que je viens de dire et à propos de quoi tu te dis : "Mais qu'est-ce qu'il me raconte cet énergumène !" :-D

Définissons par exemple z=[0;0;1;0;0;0;0;0];.
En faisant v(z), cela te retournera le troisième élément de v, c'est-à-dire v(3)=4.
Si maintenant on définit z=[1;0;1;0;1;0;1;0];, en faisant v(z), tu obtiendras le vecteur contenant les éléments v(1), v(3), v(5), v(7). Nous avons pris un élément sur deux.

La question que tu te poses sans doute maintenant est : Mais comment donc utiliser les cochonneries que tu viens de me raconter pour ne sélectionner que les éléments strictement positifs de v saperlipopette ? :-D

C'est très simple ! ;-)
Il est très facile de définir un vecteur de type booléen à partir de v qui contiendra des 1 aux positions où les éléments correspondants de v sont négatifs et des 0 aux positions où les éléments correspondants de v sont strictement positifs.
Il te suffit de faire z=(v<=0);, le vecteur booléen est (v<=0);.
Ce fameux vecteur z (tu pourras tester) est alors égal à [0;1;0;0;1;1;0;0];

Attention, ce n'est pas le propos ici, mais pour construire un vecteur de type booléen par égalité, la syntaxe est ==. Par exemple, pour avoir le vecteur booléen avec des 1 aux positions où les éléments de v sont nuls, la syntaxe est z=(v==0);, le vecteur booléen est ici (v==0);.

Il reste enfin à utiliser l'indexation logique dont je parlais au début pour enlever toutes les valeurs négatives en définissant v(z) comme matrice vide. La syntaxe est v(z)=[];, le vecteur v est alors écourté, nous lui avons enlevé trois valeurs, celles qui étaient négatives.

Ici, j'ai quelque peu détaillé les étapes mais pour faire court, il te suffit de faire v(v<=0)=[]; pour raboter la tronche de v.

Je te souhaite un bon week-end !
Messages postés
639
Date d'inscription
vendredi 17 octobre 2008
Statut
Membre
Dernière intervention
31 mai 2009
373
1
Merci
Bonsoir Pallas !

Comme je n'ai pas de support visuel, il n'est pas impossible que je te raconte des âneries, mais essayons tout de même. :-D
Si j'ai bien compris ce que tu veux faire, il y a une astuce qui vaut ce qu'elle vaut, c'est de mettre à NaN (Not-a-Number) toutes les valeurs dont tu ne veux pas qu'elles soit tracées. Comme il s'agit de valeur qui ne sont pas des nombres par définition, Matlab ne les trace pas.
Si tu veux quelques informations sur ce fameux NaN, tu peux taper help NaN ou doc NaN. La traduction résumée du début de l'aide est approximativement celle-ci...
NaN est pour Matlab une représentation arithmétique pour Not-a-Number.
NaN est obtenu pour des résultats d'opérations mathématiques non définies comme 0/0 et inf-inf.
inf quant à lui est la représentation arithmétique pour Matlab de +∞, obtenu par exemple en faisant exp(1000), 1/0, etc...

Cette digression étant terminée, voici comment tu peux procéder (si je ne suis pas à côté de la plaque concernant ta demande), le mieux est de te montrer pour un exemple. En faisant ceci :
x=(-2:0.001:2);
y=x.^2-1;
plot(x,y);
Tu obtiens une parabole qui descend en-dessous de l'axe des abscisses. Maintenant, remplaçons toues les valeurs négatives de y par des NaN et traçons à nouveau la courbe :
y(y<=0)=NaN;
plot(x,y);
Tout ce qui descendait en-dessous de l'axe des abscisses a été raboté et rien n'a été tracé. Est-ce quelque chose de ce genre que tu voulais faire ?

Je te souhaite une bien bonne nuit !
Messages postés
639
Date d'inscription
vendredi 17 octobre 2008
Statut
Membre
Dernière intervention
31 mai 2009
373
1
Merci
Bonjour Pallas !

Je suis désolé si j'étais quelque peu à côté de la plaque alors. Cela dit, je suis vraiment content que tu aies apprécié les quelques explications des messages précédents et qu'ils t'aient servi pour résoudre ton problème. Ce fut un réel plaisir pour moi d'échanger avec toi aussi.

Je vais t'ennuyer encore quelques instants cependant, en espérant que tu liras ce dernier message tout de même. :-D
J'ai le souvenir que lorsqu'on débute en Matlab, il est assez difficile de connaître toutes les optons relatives à une fonction, il faut prendre le réflexe de bien consulter l'aide, etc... on en a pas toujours le temps ou l'envie lorsqu'un programme fonctionne correctement comme il est. Cependant, parfois, on code quelque chose qui est légèrement moins compact que cela pourrait l'être en utilisant au mieux les options des différentes fonctions, ce qui n'est pas un mal quelque fois cela dit, parce qu'à force de compacter, il arrive qu'on perde en lisibilité du programme.
Bref... tout cela pour dire que si j'ai bien compris ce que tu voulais faire cette fois (on peut toujours espérer), trois lignes suffisent pour faire ce que tu voulais je pense. Je ne sais pas s'il en est ainsi de ce que tu as écrit, cela dépend de la manière dont tu as utilisé find. ;-)
Ces lignes devraient donc suffire pour enlever toutes les valeurs qui suivent la première valeur négative du vecteur y et tracer sa courbe représentative en fonction de x :
x(find(y<=0,1,'first'):end)=[];
y(find(y<=0,1,'first'):end)=[];
plot(x,y);
find(y<=0,1,'first') fournit l'indice de la première valeur négative de y et à partir de cette indice jusqu'à la fin (end), on enlève tout en remplaçant par une matrice vide. Peut-être ne suis-je pas complètement à l'ouest cette fois... :-D

Si un jour tu as de nouveau une question, totalement différente de celle de ce sujet, pense à ouvrir un nouveau sujet ; d'une part parce que je n'ai pas réponse à tout et d'autre part parce qu'on jette plus volontiers un petit coup œil aux sujets qui sont sans réponse plutôt qu'à ceux dans lesquels une personne est déjà intervenue et que si la personne qui t'avait répondu la première fois est absente, tu risques d'attendre une réponse très longtemps dans le "vieux" sujet que tu auras fait remonter. :-D
Cela dit, je ne t'apprends peut-être rien du tout si tu es plutôt habitué aux forums.

Voili, voilou...

Au plaisir et à bientôt peut-être ! ;-)
Bon dimanche !
Messages postés
639
Date d'inscription
vendredi 17 octobre 2008
Statut
Membre
Dernière intervention
31 mai 2009
373
1
Merci
Bonjour mon ami !

Nous te remercions du fond du cœur de ta participation des plus utiles.
Il est en effet grandement intéressant de répéter ce qui a été dit il y a quinze jours dans les messages 8 et 9, cela peut toujours servir... aux personnes souffrant de troubles aigus de la mémoire immédiate... ou aux poissons rouges...
Il est en effet très connu que Matlab est le logiciel de prédilection de ces adorables vertébrés aquatiques.

Je te souhaite une bien bonne fin d'après-midi !
0
Merci
Merci beaucoup pour ta réponse pertinente et très rapide!

Maintenant, il ne me reste plus qu'à expliquer au logiciel que les rayons se font absorbé par le sol càd que les morceaux de fonction qui descendent en dessous de 0 doivent être effacés.

Bonne soirée à toi aussi.
0
Merci
Après 3 lectures, je pense avoir bien compris ton raisonnement.
J'introduis donc simplement v(v<=0)=[] après avoir défini mon vecteur v( qui chez moi est le vecteur qui désigne la valeur des ordonnée de chaque points). Ce qui devrait remplacer les valeurs <=0 par le vide.

Je ne comprends pas pourquoi mais ça ne marche pas: Je n'obtiens plus de graphique du tout et mon axe des abscisse ne m'indique plus que des valeurs de 0 à 1 alors qu'il allait de 0 à 1000 avant ( l'axe des ordonnées a rétréci aussi.)
Messages postés
639
Date d'inscription
vendredi 17 octobre 2008
Statut
Membre
Dernière intervention
31 mai 2009
373
0
Merci
Désolé, je dois filer Pallas, on voit cela demain ?
Je t'explique cependant rapidement ce qui me vient en tête en lisant ton message...
Si tu écourtes le vecteur des ordonnées, il faut aussi écourter le vecteur des abscisses pour que les deux vecteurs aient la même longueur (je suis d'ailleurs étonné que tu n'aies pas eu de message d'erreur lorsque tu as demandé à Matlab de tracer les courbes).
Par exemple, si tu veux tracer v en fonction de x et que tu écourtes v de cette manière : v(v<=0)=[];, il faut aussi que tu supprimes les abscisses qui correspondaient à ces valeurs, donc tu dois d'abord commencer par x(v<=0)=[];. Si tu commences par v, cela ne marchera pas car ton vecteur v aura déjà été écourté (et il n'aura donc plus de valeurs négatives pour écourter le vecteur x.
La manipulation est donc la suivante :
x(v<=0)=[];
v(v<=0)=[];
plot(x,v);
Je te souhaite une bien bonne nuit !
0
Merci
Arf désolé tu as raison matlab m'envoyait un message d'erreur comme quoi les vecteurs n'avaient pas la même longueurs.
Je me doutais qu'il s'agissait d'une faute de ce genre.

Maintenant ça fonctionne.
Ceci dit je n'ai pas encore exactement ce que je recherchais car les courbes des rayons qui touchent le sol finissent par remonter du coup, matlab relie avec une simple droite le moment où le rayon atteint le sol et en ressort. Alors que le rayon est sensé être absorbé par le sol et ne jamais en ressortir.

Si tu as une idée n'hésite pas car je ne vois pour le moment pas d'autre solution que d'utiliser quelque chose du genre Find suivi d'une boucle (comme on m'a appris à les faire en Pascal).

En tout cas merci beaucoup pour tout le temps que tu m'as déjà consacré.

Passe une bonne nuit également.
0
Merci
Ce n'est pas exactement ce que je cherchais car il reste toujours le morceau de la courbe qui "resort" du sol alors qu'il devrait être totalement effacé.

Je me suis basé sur ce que tu m'avais dis avant pour effacer mes rayons. J'ai juste utilisé la commande "find" pour trouver l'indice de la première valeur négative du vecteur z ensuite dans le cas où r possède au moins une valeur, je supprime tout ce qu'il y a depuis la première valeur négative jusqu'à la fin du vecteur z.
Je trouve ainsi la bonne solution.

Merci encore pour ton aide. Tes explications sont vraiment claires, agréables à lire et appropriées.

Je te souhaite également une bonne nuit et te dis à la prochaine au cas où j'aurais de grosses difficultés avec la suite de mon travail et que tu daignes répondre (de nouveau) à mes questions.
0
Merci
Bonjour Pallas!

Si ca peut t'aider (et si ce n'est pas trop tard puisque le milestone est dépassé...) voici ce que je ferais:

utiliser la commande find pour trouver les éléments négatifs de ton vecteur z.
Le premier élément du vecteur qui en ressort est l'indice de ton premier z négatif.
Il suffit alors de tronquer ton vecteur z (et x également) jusque cet indice et puis "plot(x,z)"