IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Interfaces Graphiques Discussion :

[eval] Légende groupée pour plot


Sujet :

Interfaces Graphiques

  1. #1
    Invité
    Invité(e)
    Par défaut [eval] Légende groupée pour plot
    Bonjour,

    J'utilise la fonction eval pour tracer des nuages de points à partir de matrices.
    Par exemple je trace les points des matrices ip1, ip2, ... ip6 en rouge, celles des matrices ix1, ... ix6 en vert, etc.
    Je voudrais que dans ma légende les couleurs (rouge, vert, etc) n'apparaissent qu'une fois (pour les associer au texte 'IP', 'IX', etc).

    Actuellement, je procède comme il suit :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    % Exemple avec ip et ix seulement
    for i = 1:6
        if eval(['ip' num2str(i)]) ~= 0
            C(i) = plot(eval(['ip' num2str(i) '(:,1)']),log10(eval(['ip' num2str(i) '(:,5)'])),'o','MarkerFaceColor','r','MarkerEdgeColor','r');
        end
    end
    for i = 7:12
        if eval(['ix' num2str(i)]) ~= 0
            C(i) = plot(eval(['ix' num2str(i) '(:,1)']),log10(eval(['ix' num2str(i) '(:,5)'])),'o','MarkerFaceColor','g','MarkerEdgeColor','g');
        end
    end
    et à la fin, je demande

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    names = {'IP','IX'};
    ind = [1 7];
    legend(C(ind),names,'Location','SouthEast');
    Le problème : ça ne marche pas à tous les coups ... :
    Error using ==> legend at 206
    Handle must be an axes or child of an axes.
    Une idée du pourquoi ?

    Merci !!

    PS : j'ai essayé d'utiliser 'hggroup', 'parent' et ce genre de choses (dont je ne suis absolument pas familière) mais je ne vois pas comment faire en utilisant des 'eval' et des 'num2str' ...
    Dernière modification par Invité ; 05/07/2011 à 21h21. Motif: Insertion de code = ajout des balises [code] (bouton # de l'éditeur), erreurs = balises [pre]

  2. #2
    Invité
    Invité(e)
    Par défaut
    Bonsoir,

    La fonction eval est à éviter un maximum. Je te conseille de bien lire la Comment créer des variables nommées A1, A2, A3, ...,AN ?.

    Pour ton erreur, la syntaxe que tu utilises étant bonne, à mon avis tes conditions sur les itérations 1 et 7 ne sont pas toujours vraies, et ainsi C(1) et C(7) ne contiennent alors pas toujours de handle valide.

  3. #3
    Invité
    Invité(e)
    Par défaut
    Bonjour,

    Merci pour ta réponse Winjerome.
    En ce qui concerne la fonction eval, je sais que son utilisation est déconseillée mais cela ne semble pas poser de problème dans mon cas particulier et permet d'alléger l'écriture ...

    A propos de la légende, j'ai résolu mon problème. Effectivement, C(1) et C(7) étaient parfois vides. A présent, j'appelle mes plots A(1),...A(6) et B(7)...B(12) et je remplace C(1) en utilisant first(A) et C(7) en utilisant first(B). J'ai ainsi le premier non nul (fonction first).

    Merci de ton aide !
    A bientôt.

    Marion

  4. #4
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par labtoy Voir le message
    la fonction eval [...] permet d'alléger l'écriture ...
    Justement non c'est le contraire, voici ce que ton code donnerait avec le contenu de la FAQ:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    for i = 1:6
        if ip{i} ~= 0
            C(i) = plot(ip{i}(:,1),log10(ip{i}(:,5)),'o','MarkerFaceColor','r','MarkerEdgeColor','r');
        end
    end
    for i = 7:12
        if ix{i} ~= 0
            C(i) = plot(ix{i}(:,1),log10(ix{i}(:,5)),'o','MarkerFaceColor','g','MarkerEdgeColor','g');
        end
    end
    Beaucoup plus clair et lisible, non?

    Par contre une remarque: je vois par la formule des plot que tes ip{i} et ix{i} sont des tableaux. Donc tes lignes
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    if ip{i} ~= 0
    if ix{i} ~= 0
    Ont peut-être besoin des fonctions
    Dernière modification par Invité ; 17/12/2011 à 22h09.

  5. #5
    Invité
    Invité(e)
    Par défaut
    Ah d'accord, je n'avais pas compris la faq comme ça. Super alors ! Ca m'embêtait un peu d'avoir des eval à vrai dire. Je ne trouvais pas d'autre solution. Mais effectivement, c'est beaucoup plus claire comme ça. Merci !

    Il ne s'agit pas de scalaires non. Je pensais que cette écriture éviterait simplement le cas de la matrice nulle, puisque j'initialise au début
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    ip{i} = zeros;
    ix{i} = zeros;
    Je jette un oeil aux fonctions que tu me conseilles.
    Dernière modification par Invité ; 11/07/2011 à 20h44. Motif: [\code] => [/code]

  6. #6
    Invité
    Invité(e)
    Par défaut
    Bonjour,

    Avant de jeter un oeil aux fonctions any et all, j'aimerais résoudre un petit souci : j'initialise mes matrices class1, class2, etc de la manière suivante

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    for i =1:12
        class{i} = zeros;
    end
    Et j'obtiens le message d'erreur

    ??? Cell contents assignment to a non-cell array object.
    Je ne vois vraiment pas le problème ...

    PS : changement de dénomination : les matrices class1, class2 ... class6 sont les anciennes matrices ip1, ... ip6 et les matrices class7, ... class12 sont les anciennes matrices ix7, ... ix12
    Dernière modification par Jerome Briot ; 18/07/2011 à 13h42. Motif: Ajout balises [code][/code] et [pre][/pre]

  7. #7
    Rédacteur/Modérateur

    Avatar de Jerome Briot
    Homme Profil pro
    Freelance mécatronique - Conseil, conception et formation
    Inscrit en
    Novembre 2006
    Messages
    20 302
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Freelance mécatronique - Conseil, conception et formation

    Informations forums :
    Inscription : Novembre 2006
    Messages : 20 302
    Points : 52 884
    Points
    52 884
    Par défaut
    CLASS est une fonction MATLAB.

    Utilise un autre nom pour cette variable
    Ingénieur indépendant en mécatronique - Conseil, conception et formation
    • Conception mécanique (Autodesk Fusion 360)
    • Impression 3D (Ultimaker)
    • Développement informatique (Python, MATLAB, C)
    • Programmation de microcontrôleur (Microchip PIC, ESP32, Raspberry Pi, Arduino…)

    « J'étais le meilleur ami que le vieux Jim avait au monde. Il fallait choisir. J'ai réfléchi un moment, puis je me suis dit : "Tant pis ! J'irai en enfer" » (Saint Huck)

  8. #8
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par Dut Voir le message
    CLASS est une fonction MATLAB.

    Utilise un autre nom pour cette variable
    Bien que j'approuve cela, l'erreur ne vient pas de là.
    labtoy a utilisé cette variable auparavant, mais ne l'a pas utilisée en tant que tableau de cellules, d'où son erreur.

  9. #9
    Invité
    Invité(e)
    Par défaut
    Bonjour,

    Effectivement, pour avoir changé "class" en "poreclass", le problème ne vient pas de là. Merci quand même Dut.

    Winjerome : c'est pourtant la première fois que j'utilise les matrices class{i}, vu que je les initialise ...

    --

    Sinon, pour revenir au sujet initial : le problème n'est finalement pas résolu pour la légende ... J'ai actuellement un code du genre

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    legend([A B C D E F G],'legend1' 'legend2' 'legend3' 'legend4' 'legend5' 'legend6' 'legend7')
    mais du coup, si par exemple D est vide, j'aurais sur mon graph une légende où
    A est associé à legend1
    B est associé à legend2
    C est associé à legend3
    E est associé à legend4 % problème, E devrait aller avec legend5 ...
    F est associé à legend5 % idem
    G est associé à legend6 % idem

    Comment associer une légende (un mot, une chaine de caractère) à une variable pour éviter ce genre de problème ??

    Merci !
    Dernière modification par Invité ; 18/07/2011 à 19h21.

  10. #10
    Invité
    Invité(e)
    Par défaut
    Une solution, en considérant que les valeurs "vides" de C (du code précédent) sont des zéros.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    mesLegendes = {'legend1','legend2','legend3','legend4','legend5','legend6','legend7'};
    mesLegendes(~C) = [];
    legend(C(C~=0),mesLegendes)

  11. #11
    Invité
    Invité(e)
    Par défaut
    Avec un code du type

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    names = {'IP','IX'};
    names(~C) = [];
    legend(C(C~=0),names,'Location','Best');
    J'obtiens le message d'erreur suivant :

    ??? Matrix index is out of range for deletion.
    
    Error in ==> logkvsphi at 64
    names(~C) = [];
    Mais en procédant de cette façon, je ne risque pas de voir apparaitre tous les C(i) ? Des lignes telles que

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    a = find(C(1:6),1,'first');
    b = find(C(7:12),1,'first');
    ne seraient-elles pas nécessaires ?

  12. #12
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par labtoy Voir le message
    J'obtiens le message d'erreur suivant :
    Normal, names ne contient que deux champs. Dans mon code, mesLegendes doit contenir toutes les légendes et être de même taille que le vecteur C (d'où ton erreur).

    Je te conseille de regarder ce qu'est l'indexage logique

  13. #13
    Invité
    Invité(e)
    Par défaut
    C'est justement là le problème : je ne veux pas une légende par plot, mais une légende par plot de même couleur.

    Soit une première légende (appelée 'IP' ou 'class1' ou 'legend1', peu importe) s'il existe un élément entre les colonnes 1 et 6 du vecteur C (plot rouge), une deuxième ('IX'/'class2'/'legend2') s'il existe un élément entre les colonnes 7 et 12 du vecteur C (plot vert), et ainsi de suite.
    D'où mon idée de prendre le premier élément non vide (fonction find avec 'first') de C(1) à C(6), puis le premier non vide de C(7) à C(12) et ainsi de suite.

    Si une couleur n'est pas représentée, je ne veux pas que la pastille de couleur et son étiquette apparaissent dans la légende.
    Le problème survient donc lorsque tous les éléments d'une même couleur/étiquette sont vides (ex : C(1) = C(2) = ... = C(6) = 0).

  14. #14
    Invité
    Invité(e)
    Par défaut
    Bon ... Et sinon, une idée du pourquoi le code

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    for i =1:12
        class{i} = zeros;
    end
    ne fonctionne pas ?

  15. #15
    Invité
    Invité(e)
    Par défaut
    Oui: clear class juste avant ces lignes.
    Je te renvoie ici
    Ainsi que changer son nom (déjà dit aussi).

  16. #16
    Invité
    Invité(e)
    Par défaut
    Au temps pour moi, le problème était bien une utilisation de la variable class en amont dans mon programme. Je pensais que Matlab différencierait "class" et "class{i}" mais ça parait compliqué. Donc le code

    fonctionne à merveille. Merci !

    Par contre, il semblerait que je ne puisse pas écrire un code du type :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    classn{j}(l{j},:) = [A(i) B(i) C(i) D(i) k(i) E(i) F(i) G(i)];
    l{j} = l{j}+1;
    En fait, le but serait que chaque classn{j} ait un indice associé représentant le numéro de la prochaine ligne l{j} à remplir.
    A chaque itération, si on considère class1 par exemple, je remplis une ligne de class1 avec le vecteur ligne [A(i) B(i) C(i) D(i) k(i) E(i) F(i) G(i)] (la boucle sur i, variable muette, est en début de programme), puis j'incrémente l1 de manière à remplir la ligne suivante à la prochaine itération concernant class1.

    Quel est votre avis ?

  17. #17
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par labtoy Voir le message
    Je pensais que Matlab différencierait "class" et "class{i}"
    Non cela reste une seule variable, c'est juste le type qui change (matrice, tableau de cellules, structure, etc...).
    Citation Envoyé par labtoy Voir le message
    Par contre, il semblerait que je ne puisse pas écrire un code du type :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    classn{j}(l{j},:) = [A(i) B(i) C(i) D(i) k(i) E(i) F(i) G(i)];
    l{j} = l{j}+1;
    La syntaxe est bonne, après cela dépend du contenu de l{j}, A(i), B(i), ...
    Quelle erreur obtiens-tu? Est-ce
    ??? Subscripted assignment dimension mismatch.
    
    De la façon dont tu l'initialises dans ton message#14, classn{j} doit contenir UNE valeur, donc si tu fais classn{j}(l{j},:) avec la partie de droite n'étant pas un scalaire, tu auras une erreur.

  18. #18
    Invité
    Invité(e)
    Par défaut
    Bonjour,

    En tenant compte de tes remarques, j'initialise tel que

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    classn{i} = cell(length(X)*length(Y),8);
    et par la suite

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    classn{j}(l{j},:) = num2cell([A(i) B(i) C(i) D(i) k(i) E(i) F(i) G(i)]);
    pour éviter le message d'erreur de conversion impossible de double à cell.

    Mais il ne semble pas y avoir de classn1 : comment initialiser une cellule à zéro pour éviter cette erreur ?

    ??? Output argument "classn1" (and maybe others) not assigned during call to ...
    Merci

    Marion

  19. #19
    Invité
    Invité(e)
    Par défaut
    L'erreur mentionne classn1 or c'est plutôt classn non?
    Ensuite, pour ce que tu veux faire, tu peux utiliser CELLFUN comme ceci:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    classn = cellfun(@(x) zeros(length(X)*length(Y),8),cell(12,1),'uniformOutput',false)
    Puis plutôt sans num2cell si je ne m'abuse:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    classn{j}(l{j},:) = [A(i) B(i) C(i) D(i) k(i) E(i) F(i) G(i)];

  20. #20
    Invité
    Invité(e)
    Par défaut
    Euh ... Je crois qu'on s'y perd un peu ...

    Qu'entends tu par "c'est plutôt classn" ?
    Je rappelle que le but initial est de créer et de remplir facilement des matrices class1, class2, class3 ... Je ne vois rien d'ennuyeux à utiliser des cellules plutôt que des matrices, tant que ça marche.

    Ok pour le reste. Merci =)

Discussions similaires

  1. Perdu dans les Groupes pour mise en forme jours/semaines
    Par StefC30 dans le forum SAP Crystal Reports
    Réponses: 5
    Dernier message: 02/04/2008, 14h13
  2. Réponses: 6
    Dernier message: 10/08/2007, 13h38
  3. Réponses: 8
    Dernier message: 04/02/2007, 15h14

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo