Plotting with four y-axes in the same figure, with multiple datasets against one of the y-axes

70 vues (au cours des 30 derniers jours)
Jørgen Myklebust le 2 Mar 2020
I have to plot a histogram against one y-axis.
bar(hist(data,n))
I also have three datasets that goes against another y-axis.
plot(w,'g-','LineWidth',1.5)
plot(r,'c-','LineWidth',1.5)
plot(g,'m-','LineWidth',1.5)
Then I've got another dataset that has to go against a third y-axis.
plot(x,v,'r--','LineWidth',1.5)
Then atlast I've got a fourth set of data that also needs a seperate y-axis.
plot(x,P,'LineWidth',1.5) % both v and P are plotted against the same x.
In total I therefore need four y-axises. And for atleast one of them I have multiple datasets that has to be plotted.
All, but the first y-axis has to be set like this:
ax = gca;
ax.YColor = 'none';
I have tried to use some functions from the File Exchange, but plotting multiple datasets against one of the extra y-axes has given me a lot of trouble. Any help would be much appreciated.
3 commentairesAfficher 1 commentaire plus ancienMasquer 1 commentaire plus ancien
Jørgen Myklebust le 2 Mar 2020
n = 0.5:1:25.5
data = randi(25,8760,1) % too many datapoints to give you the actual data, but this will do.
w = [0.0446413353120292 0.0940964042448439 0.121372980005119 0.131358771864916 0.127988423566389 0.115499376154473 0.0979609361073778 0.0787758371993200 0.0604087827703384 0.0443542257276047 0.0312754612012046 0.0212282588722629 0.0138953796698661 0.00878474160002115 0.00537080233966300 0.00317883503789039 0.00182313469153450 0.00101401464334558 0.000547339013641821 0.000286902211231029 0.000146126026407959 7.23544123378655e-05 3.48460873563609e-05 1.63299702679374e-05 7.44963986142108e-06 3.30953527763503e-06];
r = [0.0271387653958470 0.0770863229493778 0.115174956557659 0.136862370814584 0.141414024816881 0.131514186264852 0.111974517924008 0.0881310671565062 0.0645081520148326 0.0440872670993606 0.0282123172603350 0.0169384308635643 0.00955602357926051 0.00507176148176594 0.00253464357194619 0.00119363191559679 0.000530003194841642 0.000222000728504438 8.77558092805978e-05 3.27485852875761e-05 1.15406844601935e-05 3.84150964680300e-06 1.20808568247170e-06 3.59005267847932e-07 1.00828375876343e-07 2.67674244065171e-08];
g = [0.0394337350138246 0.0602597547368911 0.0835527141261834 0.105115684041137 0.119990879322805 0.124280418632199 0.116796797649382 0.0995939413789165 0.0770563902486737 0.0540951285841574 0.0344573132377427 0.0199149133329043 0.0104435749288667 0.00496928276145731 0.00214541833890487 0.000840434794242614 0.000298723793536455 9.63406038265979e-05 2.81917910936216e-05 7.48530893778544e-06 1.80331064697308e-06 3.94189562378176e-07 7.81832015732127e-08 1.40700466432989e-08 2.29747809864003e-09 3.40393281257451e-10];
% ylim([0 0.15]) I have used this as the ylimit for w, r and g.
v = [0 0 0 0 0.367139430431131 0.502834163918477 0.522153856613164 0.537757579733529 0.537859265581607 0.538833771477196 0.538079549239866 0.537595840971493 0.537111388964062 0.531006943167029 0.522344145919510 0.519543087330099 0.516289824043778 0.508151460804334 0.496569929225097 0.495014645374997 0.486826884751680 0.450351358351976 0.408239186354676 0.365479804502495 0.326346160383228 0.290233999659861 0.259353844346434 0.232486199303644 0.208723582898165 0.187867485004736 0.169700003399278 0.153801486750378 0.139828494011857 0.127498124266926 0.116575923360994 0.106866474443860 0.0982060204856935 0.0904566381414826 0.0835016054049518 0.0772416947652610 0.0715921889340706 0.0664804644706333 0.0618440245624193 0.0576288891768086 0.0537882711751094 0.0502814824886751 0.0470730263394892 0.0441318406497647 0.0414306648924020 0.0389455081792494 0 0 0 0];
% ylim([0 0.593]) I have used this as for v.
P = [0 0 0 0 4 10.7000000000000 19.2000000000000 31.4000000000000 46.8800000000000 66.8700000000000 91.6000000000000 121.810000000000 158 198.600000000000 244 298.500000000000 360 425 493 578 663 710 740 757 768 772 776 779 780 780 780 780 780 780 780 780 780 780 780 780 780 780 780 780 780 780 780 780 780 780 0 0 0 0];
% ylim([0 800]) I have used this for P.
Jørgen Myklebust le 2 Mar 2020
Modifié(e) : Jørgen Myklebust le 2 Mar 2020
I have tried:
Maybe this one could work?

Connectez-vous pour commenter.

Réponse acceptée

Kelly Kearney le 3 Mar 2020
While there are a lot of FEX options out there, I really think it's easier to manually control things once you start playing around with more than 2 overlapping axes. You just need to be very explicit about which axis each plot command points to. Here's an example:
% Step 1: Create 4 axes, all on top of each other
ax(1) = axes('position', [0.2 0.1 0.7 0.8]);
ax(2) = axes('position', ax(1).Position);
ax(3) = axes('position', ax(1).Position);
ax(4) = axes('position', ax(1).Position);
% Step 2: plot your data on the appropriate axes
bar(ax(1), n, hist(data,n));
hold(ax(2), 'on');
plot(ax(2), 1:length(w), w,'g-','LineWidth',1.5);
plot(ax(2), 1:length(r), r,'c-','LineWidth',1.5);
plot(ax(2), 1:length(g), g,'m-','LineWidth',1.5);
plot(ax(3), x,v,'r--','LineWidth',1.5);
plot(ax(4), x,P,'b', 'LineWidth',1.5);
% Step 3: match up the x-axis limits for all axes. Also, remove axes
% background colors. Make all but one x-axis invisible.
set(ax, 'xlim', [0 26], 'color', 'none');
set(ax(2:end), 'xcolor', 'none', 'ycolor', 'none');
You requested to hide all but the first y-axis, which means you don't need to deal with the overlapping axis lines. But if you do, I like to handle this by 1) moving at least 1 y-axis to the opposite side, and 2) offsetting the remaining axes. I do #2 by creating an additional axis that is linked to the original but displaced, with only the y-axis visible (see offsetaxis.m, here).
set(ax, 'ycolor', 'k'); % ... or just don't set to 'none'
set(ax, 'box', 'off'); % Remove extra y-axis on right side
set(ax(2), 'yaxisloc', 'right'); % Move one y-axis to the right
axo(1) = offsetaxis(ax(3), 'y', 0.1); % offset the others
axo(2) = offsetaxis(ax(4), 'y', 0.2);
set(axo(1), 'ycolor', 'r'); % change the colors of the offset axes to match data
set(axo(2), 'ycolor', 'b');
So this final figure includes 6 different axes, but only certain bits of each are visible, creating the desired look.
3 commentairesAfficher 1 commentaire plus ancienMasquer 1 commentaire plus ancien
Sahil Bishnoi le 25 Fév 2021
Hey Kelly,
I have the same issue plotting multiple Y-axis with a common x-axis.
1. X-axis is common time series
2. Y1 is the trace in black color which I need on primary y-axis
3. Y2 is the trace in blue which I need on left side offset to primary y-axis (limit [0 120])
4. Y3 is the trace in magenta which I need again on left side offset to Y2 (limit [0 1000])
I tried your code and offset function but my y-axes are not getting offset as shown below.
Kelly Kearney le 25 Fév 2021
Can you upload some example code that demonstrates what you've tried so far? It looks like you have successfully created at least the 3 overlapping plotting axes; are you getting any error messages when you run offsetaxis?

Connectez-vous pour commenter.

Plus de réponses (1)

Modifié(e) : Kelly Kearney le 8 Nov 2023
I am trying to use the offsetaxis.m for multiple y axes ( 4 y axes) . I have difficulty in placing the legends, Can you please help me?
Thank you.
Pratheeba
Here's my code:
% Step 1: Create 4 axes, all on top of each other
figure()
ax(1) = axes('position', [0.2 0.1 0.7 0.8]);
ax(2) = axes('position', ax(1).Position);
ax(3) = axes('position', ax(1).Position);
ax(4) = axes('position', ax(1).Position);
% Step 2: plot your data on the appropriate axes
plot(ax(1), t,m, 'r-', 'LineWidth',1.5)
ylabel(ax(1), 'Mass flowrate (kg/s)')
set(ax(2), 'xlim', [3e-3 13e-3], 'color', 'k');
hold(ax(2), 'on');
plot(ax(2), t_T, T, 'g-','LineWidth',1.5);
set(ax(2), 'ylim', [300 520], 'color', 'r');
plot(ax(3), t, CO_constant,'r-','LineWidth',1.5);
set(ax(3), 'ylim', [0 150], 'color', 'b');
plot(ax(4), t, H2_constant,'m-','LineWidth',1.5);
set(ax(4), 'ylim', [0 40], 'color', 'c');
%plot(ax(3), x,v,'r--','LineWidth',1.5);
%plot(ax(4), x,P,'b', 'LineWidth',1.5);
% Step 3: match up the x-axis limits for all axes. Also, remove axes
% background colors. Make all but one x-axis invisible.
set(ax, 'xlim', [0 90], 'color', 'none');
set(ax(2:end), 'xcolor', 'none', 'ycolor', 'none');
set(ax, 'ycolor', 'k'); % ... or just don't set to 'none'
set(ax, 'box', 'off'); % Remove extra y-axis on right side
set(ax(2), 'yaxisloc', 'right'); % Move one y-axis to the right
axo(1) = offsetaxis(ax(3), 'y', 0.1); % offset the others
axo(2) = offsetaxis(ax(4), 'y', 0.2);
set(axo(1), 'ycolor', 'r'); % change the colors of the offset axes to match data
set(axo(2), 'ycolor', 'b');
2 commentairesAfficher AucuneMasquer Aucune
Kelly Kearney le 8 Nov 2023
Modifié(e) : Kelly Kearney le 8 Nov 2023
I'm not able to replicate your code without the data. But in general, you should be able to place legends in any of the axes using the usual syntax. The only trick is to call legend with the subset input (i.e. with individual line handles as the first input); just using the default without a target handle will only label the current axis. Personally, I prefer that syntax any time I call legend, even on a single axis, since it avoids ambiguity!
Thank you so much @Kelly Kearney
Here's the data:
clc;
clear all;
close all;
% Original V
t1 = 0:0.001:10; % 0 to 10 seconds
m1 = ones(size(t1)) * 0.00313; % Constant at 0.00313 kg/s
t2 = 10:0.001:20; % 10 to 20 seconds
m2 = ones(size(t2)) * 0.00626; % Constant at 0.00626 kg/s
t3 = 20:0.001:40; % 20 to 40 seconds
m3 = ones(size(t3)) * 0.00313; % Constant at 0.00313 kg/s
t4 = 40:0.001:60; % 40 to 60 seconds
m4 = ones(size(t4)) * 0.01252; % Constant at 0.01252 kg/s
t5 = 60:0.001:90; % 60 to 90 seconds
m5 = ones(size(t5)) * 0.00313; % Constant at 0.00313 kg/s
t = [t1, t2, t3, t4, t5]; % Combine time intervals
m = [m1, m2, m3, m4, m5]; % Combine mass flow rates
% Time-shifted
t1s = 0:0.001:20;
m1s = ones(size(t1s)) * 0.00313; % Constant at 0.00313 kg/s
t2s = 20:0.001:30; % 10 to 20 seconds
m2s = ones(size(t2s)) * 0.00626; % Constant at 0.00626 kg/s
t3s = 30:0.001:40; % 20 to 40 seconds
m3s = ones(size(t3s)) * 0.00313; % Constant at 0.00313 kg/s
t4s = 40:0.001:50; % 40 to 60 seconds
m4s = ones(size(t4s)) * 0.00313; % Constant at 0.01252 kg/s
t5s = 50:0.001:60; % 60 to 90 seconds
m5s = ones(size(t5s)) * 0.01252; % Constant at 0.00313 kg/s
t6s = 60:0.001:70; % 60 to 90 seconds
m6s = ones(size(t6s)) * 0.01252; % Constant at 0.00313 kg/s
t7s = 70:0.001:80; % 60 to 90 seconds
m7s = ones(size(t7s)) * 0.00313; % Constant at 0.00313 kg/s
t8s = 80:0.001:90; % 60 to 90 seconds
m8s = ones(size(t8s)) * 0.00313; % Constant at 0.00313 kg/s
t9s = 90:0.001:100; % 60 to 90 seconds
m9s = ones(size(t9s)) * 0.00313; % Constant at 0.00313 kg/s
ts = [t1s, t2s, t3s, t4s, t5s, t6s, t7s, t8s, t9s]; % Combine time intervals
ms = [m1s, m2s, m3s, m4s, m5s, m6s, m7s, m8s, m9s]; % Combine mass flow rates
% Shrunk V
t1v = 0:0.001:10; % 0 to 10 seconds
m1v = ones(size(t1v)) * 0.004; % Constant at 0.00313 kg/s
t2v = 10:0.001:20; % 10 to 20 seconds
m2v = ones(size(t2v)) * 0.005; % Constant at 0.00626 kg/s
t3v = 20:0.001:40; % 20 to 40 seconds
m3v = ones(size(t3v)) * 0.004; % Constant at 0.00313 kg/s
t4v = 40:0.001:60; % 40 to 60 seconds
m4v = ones(size(t4v)) * 0.010; % Constant at 0.01252 kg/s
t5v = 60:0.001:90; % 60 to 90 seconds
m5v = ones(size(t5v)) * 0.004; % Constant at 0.00313 kg/s
tv = [t1v, t2v, t3v, t4v, t5v]; % Combine time intervals
mv = [m1v, m2v, m3v, m4v, m5v]; % Combine mass flow rates
% Temperature
% Define the time intervals and temperature values
% Original T
t_1 = 0:0.001:10; % 0 to 10 seconds
T1 = 300 + (t_1 / 10) * 200; % Linear ramp from 300 K to 500 K
t_2 = 10:0.001:20; % 10 to 20 seconds
T2 = ones(size(t_2)) * 500; % Constant at 500 K
t_3 = 20:0.001:30; % 20 to 30 seconds
T3 = 500 - (t_3 - 20) / 10 * 100; % Linear ramp from 500 K to 400 K
t_4 = 30:0.001:40; % 30 to 40 seconds
T4 = ones(size(t_4)) * 400; % Constant at 400 K
t_5 = 40:0.001:50; % 40 to 50 seconds
T5 = 400 + (t_5 - 40) / 10 * 100; % Linear ramp from 400 K to 500 K
t_6 = 50:0.001:60; % 50 to 60 seconds
T6 = ones(size(t_6)) * 500; % Constant at 500
t_7 = 60:0.001:70; % 60 to 70 seconds
T7 = 500 - (t_7 - 60) / 10 * 200; % Linear ramp from 500 K to 300 K
t_8 = 70:0.001:90; % 70 to 90 seconds
T8 = ones(size(t_8)) * 300; % Constant at 300
t_T = [t_1, t_2, t_3, t_4, t_5, t_6, t_7, t_8]; % Combine time intervals
T = [T1, T2, T3, T4, T5, T6, T7, T8]; % Combine Temperatures
% Shrunk T
% Define the time vector from 0 to 90 seconds with a step of 0.001 seconds
t_Ts = 0:0.001:90;
% Initialize an array to store the temperature values
temperature = zeros(size(t));
% Define the temperature profile using slopes
for i = 1:length(t_Ts)
if t_Ts(i) >= 0.0 && t_Ts(i) < 10.0
temperature(i) = 350.0 + (t(i) - 0.0) * 10.0; % Linear ramp from 350 K to 450 K
elseif t_Ts(i) >= 10.0 && t_Ts(i) < 20.0
temperature(i) = 450.0; % Constant at 450l K
elseif t_Ts(i) >= 20.0 && t_Ts(i) < 30.0
temperature(i) = 450.0 - (t_Ts(i) - 20.0) * 5.0; % Linear ramp from 450 K to 400 K
elseif t_Ts(i) >= 30.0 && t_Ts(i) < 40.0
temperature(i) = 400.0; % Constant at 400 K
elseif t_Ts(i) >= 40.0 && t_Ts(i) < 50.0
slope = (450.0 - 400.0) / 10.0; % Slope from 400 K to 450 K
temperature(i) = 400.0 + (t_Ts(i) - 40.0) * slope;
elseif t_Ts(i) >= 50.0 && t_Ts(i) < 60.0
temperature(i) = 450.0; % Constant at 450 K
elseif t_Ts(i) >= 60.0 && t_Ts(i) < 70.0
slope = -10.0; % Slope from 450 K to 350 K
temperature(i) = 450.0 + (t_Ts(i) - 60.0) * slope;
elseif t_Ts(i) >= 70.0 && t_Ts(i) <= 90.0
temperature(i) = 350.0; % Constant at 350 K
end
end
% % Plot the temperature vs. time
% plot(t_Ts, temperature);
% xlabel('Time (s)');
% ylabel('Temperature (K)');
% title('Temperature Profile');
% grid on;
% Variable concentration
% Define the time vector from 0 to 90 seconds with a step of 0.001 seconds
tc = 0:0.001:90;
% Initialize arrays to store CO and H2 mass fractions
mass_fraction_CO = zeros(size(tc));
mass_fraction_H2 = zeros(size(tc));
% Define the mass fraction schedule for CO and H2
for i = 1:length(tc)
if tc(i) >= 0.0 && tc(i) < 10.0
mass_fraction_CO(i) = 9.7073e-5; % Constant CO mass fraction at 9.7073e-5 from 0 to 10 seconds
mass_fraction_H2(i) = 2.2881e-6; % Constant H2 mass fraction at 2.2881e-6 from 0 to 10 seconds
elseif tc(i) >= 10.0 && tc(i) < 20.0
mass_fraction_CO(i) = 1.4561e-4; % CO mass fraction at 1.4561e-4 from 10 to 20 seconds
mass_fraction_H2(i) = 3.4323e-6; % H2 mass fraction at 3.4323e-6 from 10 to 20 seconds
elseif tc(i) >= 20.0 && tc(i) < 40.0
mass_fraction_CO(i) = 9.7073e-5; % Constant CO mass fraction at 9.7073e-5 from 20 to 40 seconds
mass_fraction_H2(i) = 2.2881e-6; % Constant H2 mass fraction at 2.2881e-6 from 20 to 40 seconds
elseif tc(i) >= 40.0 && tc(i) < 60.0
mass_fraction_CO(i) = 2.9124e-4; % Constant CO mass fraction at 2.9124e-4 from 40 to 60 seconds
mass_fraction_H2(i) = 6.9342e-6; % Constant H2 mass fraction at 6.9342e-6 from 40 to 60 seconds
elseif tc(i) >= 60.0 && tc(i) < 90.0
mass_fraction_CO(i) = 9.7073e-5; % Constant CO mass fraction at 9.7073e-5 from 60 to 90 seconds
mass_fraction_H2(i) = 2.2881e-6; % Constant H2 mass fraction at 2.2881e-6 from 60 to 90 seconds
end
end
% Plot the CO and H2 mass fractions vs. time
plot(tc, mass_fraction_CO, 'r', 'LineWidth', 2);
hold on;
plot(tc, mass_fraction_H2, 'b', 'LineWidth', 2);
xlabel('Time (s)');
ylabel('Mass Fraction');
title('CO and H2 Mass Fractions');
legend('CO', 'H2');
grid on;
%% Paper Profiles
CO_constant = ones(size(t))*100; % constant at 100 ppm
H2_constant = ones(size(t))*33; % constant at 100 ppm
I could not get what you suggested. Can you please help me add the legends?
Thank you
Pratheeba

Connectez-vous pour commenter.

Catégories

En savoir plus sur MATLAB Report Generator dans Help Center et File Exchange

R2019a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by