2
votes

Bar plot avec deux axes y

J'ai le code suivant pour un tracé avec 2 axes y dans MATLAB. Je suis heureux que la fonction 2 axes fonctionne, cependant, je voudrais éviter le chevauchement des barres. En outre, les catégories sur l'axe de droite doivent avoir des couleurs différentes, pas seulement du jaune, mais il doit être clair qu'elles sont tracées sur l'axe de droite et non sur l'axe de gauche. Comment cela peut-il être fait?

EONMW = [100 399 500];
RWEMW = [200 996 120];
GermanByEON = [0.2 0.4 0.5];
GermanByRWE = [0.1 0.5 0.9];
EONGermanPortfolio = [0.7 0.2 0.1];
RWEGermanPortfolio = [0.8 0.3 0.6];
years = [2010 2012 2014];
% Plot
values1 = [EONMW; RWEMW]';
values2 = [GermanByEON; GermanByRWE; EONGermanPortfolio; RWEGermanPortfolio]';
years1 = [years; years]';
years2 = [years; years; years; years]';
figure;
bar(years1,values1);
ylabel('Utilities generation portfolio in MW')  
yyaxis right
bar(years2,values2);
legend('EON German portfolio in MW', 'RWE German portfolio in MW',...
    'Percentage of German portfolio by EON', 'Percentage of German portfolio by RWE',...
    'EON"s percentage of generation in Germany', 'RWE"s percentage of generation in Germany')
legend('Location','northwest')
ylabel('Utilities generation portfolio as percentages')  

 entrez la description de l'image ici


4 commentaires

OK, voir ma modification!


La modification clarifie la question, mais le fait que vous ayez 3 métriques différentes sur un seul tracé n'est pas très clair du point de vue de la visualisation des données (personnelles) ... envisagez d'utiliser simplement subplot à la place, vous pouvez divisez vos données en tracés empilés afin qu'ils s'alignent sur l'axe des x, mais le but et le contenu de chaque tracé sont plus clairs. Cela vous évitera également de vous enliser dans des solutions de contournement pour ce qui précède, ce qui, je ne suis pas sûr, sera facile pour bar . La raison pour laquelle toutes les barres yyaxis right sont de la même couleur est que vous savez sur quel axe elles se trouvent - comment le sauriez-vous autrement?


Lié au même OP: stackoverflow.com/questions / 54071530 /…


Je ne recommanderais pas de tracer les données de cette manière (même avec la suggestion de @ Dev-iL). Je ne vois aucun avantage à tracer ces graphiques à barres avec 2 axes y, au lieu d'utiliser 2 sous-graphiques verticaux, avec des années alignées. Pourquoi tracer les barres ensemble si elles ne peuvent pas être comparées de toute façon?


3 Réponses :


7
votes

Je suis d'accord qu'il est quelque peu difficile de lire ce genre d'intrigue, mais peut-être y a-t-il un moyen d'améliorer un peu la situation.

La principale chose que j'ai changé a été d'ajouter des barres invisibles (en utilisant NaN code >) pour que l'ordre des couleurs reste intact:

function q54071610
EONMW = [100 399 500];
RWEMW = [200 996 120];
GermanByEON = [0.2 0.4 0.5];
GermanByRWE = [0.1 0.5 0.9];
EONGermanPortfolio = [0.7 0.2 0.1];
RWEGermanPortfolio = [0.8 0.3 0.6];
years = [2010 2012 2014];
% Plot
values1 = [[EONMW; RWEMW].' NaN(3,4)];
values2 = [NaN(3,2) [GermanByEON; GermanByRWE; EONGermanPortfolio; RWEGermanPortfolio].'];
years1 = repmat(years.', [1,6]);
figure;
bar(years1,values1, 'EdgeColor', 'b', 'LineWidth', 2);
ylabel('Utilities generation portfolio in MW')  
yyaxis right
hB = bar(years1,values2, 'EdgeColor', 'r', 'LineWidth', 2);
c = lines(6);
for ind1 = 1:6
  hB(ind1).FaceColor = c(ind1, :);
end
legend('EON German portfolio in MW', 'RWE German portfolio in MW',...
    'Percentage of German portfolio by EON', 'Percentage of German portfolio by RWE',...
    'EON"s percentage of generation in Germany', 'RWE"s percentage of generation in Germany')
legend('Location','northwest')
ylabel('Utilities generation portfolio as percentages')

Ce qui donne:

 entrez la description de l'image ici p >

Vous devez maintenant expliquer que les barres encadrées en rouge appartiennent à l'axe droit alors que les barres encadrées en bleu appartiennent à la gauche.


2 commentaires

C'est sympa, merci! Seul hic: dans la légende les entrées n'apparaissent qu'avec des cadres bleus ...


Oui, j'ai remarqué cela. Je ne sais pas ce qui peut être fait (l'édition des entrées de légende devrait être possible mais probablement difficile). Ce que vous pouvez faire, c'est peut-être tracer un autre diagramme à barres, à l'avance, avec toutes les valeurs y NaN , puis afficher la légende (qui aura de petits cadres noirs autour des entrées, comme dans votre image). Ajoutez simplement la barre (années1, NaN * valeurs1); tenez bon; après figure; et voyez si le résultat fonctionne pour vous.



0
votes

Il est préférable de définir bar (x, y) comme b = bar (x, y) puis de contrôler les options de b code > l'un d'eux est b.FaceColor . Jetez un œil au code suivant

%%%%%%%%%%%%
%%%%%%%%%%%%
%% Defining colors
b1(1).FaceColor=[1 0 0];
b1(2).FaceColor=[0 1 0];
b2(1).FaceColor=[0 0 1];
b2(2).FaceColor=[1 1 0];
b2(3).FaceColor=[0 1 1];
b2(4).FaceColor=[1 0 1];
%%%%%%%%%%%%
%%%%%%%%%%%%
%%

qui est votre code plus le bloc suivant

EONMW = [100 399 500];
RWEMW = [200 996 120];
GermanByEON = [0.2 0.4 0.5];
GermanByRWE = [0.1 0.5 0.9];
EONGermanPortfolio = [0.7 0.2 0.1];
RWEGermanPortfolio = [0.8 0.3 0.6];
years = [2010 2012 2014];
x=0.2;
% Plot
values1 = [EONMW; RWEMW]';
values2 = [GermanByEON; GermanByRWE; EONGermanPortfolio; RWEGermanPortfolio]';
years1 = [years; years]';
years2 = [years; years; years; years]';
figure;
b1=bar(years1,values1,x*0.66);
ylabel('Utilities generation portfolio in MW')  
yyaxis right
b2=bar(years2,values2,x);
%%%%%%%%%%%%
%%%%%%%%%%%%
%% Defining colors
b1(1).FaceColor=[1 0 0];
b1(2).FaceColor=[0 1 0];
b2(1).FaceColor=[0 0 1];
b2(2).FaceColor=[1 1 0];
b2(3).FaceColor=[0 1 1];
b2(4).FaceColor=[1 0 1];
%%%%%%%%%%%%
%%%%%%%%%%%%
%%
legend('EON German portfolio in MW', 'RWE German portfolio in MW',...
    'Percentage of German portfolio by EON', 'Percentage of German portfolio by RWE',...
    'EON"s percentage of generation in Germany', 'RWE"s percentage of generation in Germany')
legend('Location','northwest')
ylabel('Utilities generation portfolio as percentages')  

et le résultat est le suivant p >

 entrez la description de l'image ici

également une option de déclenchement x a été ajoutée pour contrôler la largeur de la barre .


5 commentaires

Mais comment savoir maintenant quelle barre appartient à quel axe?


Dans le code ci-dessus, après avoir défini b = bar (x, y), b devient un vecteur chaque composant étant le panneau de contrôle de la barre correspondant. Par exemple, si b = bar (x, y) où x et y sont 2 * 20 vecteurs, alors b maintient un vecteur 2 * 1 avec b (1) relatif à bar (x (1, :), y (1 ,: )) et b (2) relatifs à bar (x (2, :), y (2, :))


@mostafa Je crois qu'il voulait demander comment le spectateur comprend-il s'il doit lire la valeur y à partir de l'axe gauche ou droit?


Voulez-vous dire lorsqu'il est imprimé avec une encre noire sur papier (pour quelles couleurs deviennent indistinctes)? Sinon, je pense que les couleurs et la légende s'expliquent d'elles-mêmes ...


@MostafaAyaz Avant même d'imprimer ... Puisque nous avons deux axes y qui signifient des choses différentes (il ne s'agit pas simplement de convertir des unités, la signification des axes est complètement différente). Maintenant, chaque barre doit être lue selon l'axe y correct , donc la question est: comment votre suggestion indique-t-elle au lecteur s'il doit regarder l'axe droit ou l'axe gauche? J'espère que c'est clair maintenant.



1
votes

Je ne suis pas sûr de la signification exacte de ces barres, et j'ai donc peut-être manqué le point de la figure (qui pourrait être le principal problème ici). Cependant, je trouve ce mode de présentation peu agréable et trompeur, car il faut beaucoup d'efforts de la part du lecteur pour comprendre quelle valeur appartient à quelle barre, et ce qui est comparable et ce qui ne l'est pas.

Ce que je suggère ici, ne l'est pas. une réponse directe au problème technique (que vous avez déjà obtenu de @ Dev-iL), mais une solution différente pour le problème plus basique - comment visualiser ces données? Je crois que si je comprends ce que les nombres représentent (pourcentage par rapport à quoi?) Et ce que vous voulez souligner avec ce graphique, je peux trouver une meilleure solution.

Premièrement, le code: p >

EONMW = [100 399 500];
RWEMW = [200 996 120];
GermanByEON = [0.2 0.4 0.5];
GermanByRWE = [0.1 0.5 0.9];
EONGermanPortfolio = [0.7 0.2 0.1];
RWEGermanPortfolio = [0.8 0.3 0.6];
years = [2010 2012 2014].';
values1 = [EONMW; RWEMW].';
values2 = [GermanByEON; GermanByRWE; EONGermanPortfolio; RWEGermanPortfolio].'*100;

% Plot
colMap = mat2cell(lines(2),[1 1],3); % Choose your favorite colors
figure(2);
% upper plot:
subplot 211
b = bar(years,values1);
set(b,{'FaceColor'},colMap)
xticklabels({}) % remove the years labels, the bottom axes will show them
ylabel('Utilities generation portfolio in MW')
legend('EON German', 'RWE German',...
    'Location','northwest')

% bottom plot
subplot 212
b = bar(years,values2);
set(b,{'FaceColor'},repmat(colMap,2,1)) % matching the colors by topic
set(b,{'FaceAlpha'},{1;1;0.6;0.6}) % distiguish between related mesures
xlabel('Year')
ylabel('Utilities generation portfolio (%)')
legend('German portfolio by EON', 'German portfolio by RWE',...
    'EON''s generation in Germany', 'RWE''s generation in Germany',...
    'Location','north')

Le résultat: entrez la description de l'image ici

Les principales choses que j'ai changées:

  1. Divisez les barres par les unités de l'axe des y, mais alignez-les par l'axe des x
  2. Faire correspondre les couleurs des barres associées entre les tracés
  3. Raccourcir les légendes et les libellés

Bonne chance!


0 commentaires