How to create a custom profile in matlab plots

4 vues (au cours des 30 derniers jours)
Sachin Hegde
Sachin Hegde le 24 Juil 2024
Modifié(e) : Umar le 25 Juil 2024
Hello Everyone,
I am trying to create a profile based on user defined inputs. The profile consists of different modes each having a certain duration and order as defined by the user.
I have uploaded a picture which shows how i want the profile to look like.
Additionally i have coded to some extent, but i am struggling to get it right.
Also i would like to break the number of cycles for dynamic elements and use '...' to show continuity. However, on th etime axis i would like to have the actual value instead of shortened periods by discontinuity.
I kindly request for support and i thank you in advance.
Vconst.val = [1, 0.85, 0.6, 0.4];
Vconst.txt = {'OCV', 'Idle', 'Mid Load', 'High Load'};
Vdyn.val = [0.8, 0.7, 0.8, 0.5, 1.5, 1];
Vdyn.txt = {'Dynamic Low', 'Dyn low trough', 'Dynamic High', 'Dyn high trough', 'SUSD', 'SUSD trough'};
% Define the order of phases and durations
order = {'OCV', 'SUSD', 'OCV', 'Mid Load', 'High Load', 'Mid Load', 'Dynamic Low', 'Mid Load', 'Dynamic High', 'OCV'}; % duration in s for Vconst elements, nr. of cycles for Vdyn elements
durations = [100, 10, 200, 100, 50, 50, 4, 50, 4, 100]; % Corresponding durations in seconds or cycles
% Initialize time and voltage vectors
time = [];
voltage = [];
current_time = 0;
% Generate time and voltage vectors
for i = 1:length(order)
phase = order{i};
duration = durations(i);
t = current_time + (0:0.1:duration);
if ismember(phase, {'OCV', 'Idle', 'Mid Load', 'High Load'})
% Constant phases
t = current_time + (0:0.1:duration);
V_idx = find(strcmp(Vconst.txt, phase));
v = Vconst.val(V_idx) * ones(size(t));
time_act(i) = t(end);
else
% Dynamic phases
n_cycles = duration; % Number of dynamic cycles
t_dynamic_full = [];
v_dynamic_full = [];
Vdyn_idx = find(strcmp(Vdyn.txt, phase));
peak_height = Vdyn.val(Vdyn_idx);
trough_height = Vdyn.val(Vdyn_idx + 1);
nr_pts = 50;
for j = 1:n_cycles
t_cycle = current_time + (0:1:nr_pts);
tri_wave = sawtooth(2 * pi * (1/nr_pts) * (t_cycle - current_time), 0.5);
tri_wave = (peak_height - trough_height) * tri_wave / 2 + (peak_height + trough_height) / 2;
tri_wave(tri_wave > peak_height) = peak_height;
tri_wave(tri_wave < trough_height) = trough_height;
t_dynamic_full = [t_dynamic_full, t_cycle];
v_dynamic_full = [v_dynamic_full, tri_wave];
current_time = t_cycle(end);
end
time_act(i) = t_dynamic_full(end);
if n_cycles > 3
t_dynamic_1 = t_dynamic_full(1:nr_pts*2+2);
v_dynamic_1 = v_dynamic_full(1:nr_pts*2+2);
t_dynamic_2 = t_dynamic_full(nr_pts*3+3:nr_pts*4+4);
v_dynamic_2 = v_dynamic_full(nr_pts*3+3:nr_pts*4+4);
t_continuity = t_dynamic_full(nr_pts*2+4:nr_pts*3+2);
v_continuity = NaN * ones(size(t_continuity));
t = [t_dynamic_1, t_continuity, t_dynamic_2];
v = [v_dynamic_1, v_continuity, v_dynamic_2];
else
t = t_dynamic_full;
v = v_dynamic_full;
end
end
time = [time, t];
voltage = [voltage, v];
current_time = t(end);
if i>1
time_act(i) = time_act(i)+time_act(i-1);
else
end
end
% Plot the voltage over time
figure;
plot(time, voltage, 'LineWidth', 1.5);
xlabel('Time (s)');
ylabel('Voltage (V)');
title('User Defined Plot with Flexible Phase Order and Durations');
grid on;
ylim([0 2])
yticklabels([])
  3 commentaires
Sachin Hegde
Sachin Hegde le 25 Juil 2024
Hello Umar,
First of all thank you. But i think there was some misunderstanding. For the dynamic cycles i do not want to have all the cycles shown (attached figure in the original post shows how i want it). I want to only show 2 cycles followed by '...' and finally the last cycle (something like this ^^...^). I need time axis to just show the values at the end of each phase.
Umar
Umar le 25 Juil 2024
Modifié(e) : Umar le 25 Juil 2024

Hi Sachin,

I spent time by updating your code by showing values at end of each phase and to check if there are more than 2 cycles for the last dynamic phase. However, I left all cycles shown on purpose for you to figure out rest of the code snippet and figure out adding lines of code for 2 cycles followed by '...' and finally the last cycle (something like this ^^...^ because if I do all the work, you will not be able to learn a lot about your project. In my opinion, you were looking for clues and were struggling figuring it out. Hope, I did help you out figuring out most things. Here is the updated code along with attached plot.

Vconst.val = [1, 0.85, 0.6, 0.4];

Vconst.txt = {'OCV', 'Idle', 'Mid Load', 'High Load'};

Vdyn.val = [0.8, 0.7, 0.8, 0.5, 1.5, 1];

Vdyn.txt = {'Dynamic Low', 'Dyn low trough', 'Dynamic High', 'Dyn high trough', 'SUSD', 'SUSD trough'};

% Define the order of phases and durations

order = {'OCV', 'SUSD', 'OCV', 'Mid Load', 'High Load', 'Mid Load', 'Dynamic Low', 'Mid Load', 'Dynamic High', 'OCV'}; % duration in s for Vconst elements, nr. of cycles for Vdyn elements

durations = [100, 10, 200, 100, 50, 50, 4, 50, 4, 100]; % Corresponding durations in seconds or cycles

% Initialize time and voltage vectors

time = [];

voltage = [];

current_time = 0;

% Generate time and voltage vectors

for i = 1:length(order)

    phase = order{i};
    duration = durations(i);
    if ismember(phase, {'OCV', 'Idle', 'Mid Load', 'High Load'})
        % Constant phases
        t = current_time + (0:0.1:duration);
        V_idx = find(strcmp(Vconst.txt, phase));
        v = Vconst.val(V_idx) * ones(size(t));
        time_act(i) = t(end);
    else
        % Dynamic phases
        n_cycles = duration;  % Number of dynamic cycles
        t_dynamic_full = [];
        v_dynamic_full = [];
        Vdyn_idx = find(strcmp(Vdyn.txt, phase));
        peak_height = Vdyn.val(Vdyn_idx);
        trough_height = Vdyn.val(Vdyn_idx + 1);
        nr_pts = 50;
        % Calculate the number of breaks needed based on the number of cycles
        n_breaks = n_cycles - 1;
        for j = 1:n_cycles
            t_cycle = current_time + (0:1:nr_pts);
            tri_wave = sawtooth(2 * pi * (1/nr_pts) * (t_cycle - current_time), 0.5);
            tri_wave = (peak_height - trough_height) * tri_wave / 2 + (peak_height + trough_height) / 2;
            tri_wave(tri_wave > peak_height) = peak_height;
            tri_wave(tri_wave < trough_height) = trough_height;
            t_dynamic_full = [t_dynamic_full, t_cycle];
            v_dynamic_full = [v_dynamic_full, tri_wave];
            current_time = t_cycle(end);
        end
        time_act(i) = t_dynamic_full(end);
        % Check if breaks are needed
        if n_breaks > 0
            % Calculate the number of points per break
            nr_pts_per_break = floor(nr_pts / (n_breaks + 1));
            % Initialize arrays for breaks
            t_breaks = [];
            v_breaks = [];
            % Generate breaks
            for k = 1:n_breaks
                t_break = current_time + (0:1:nr_pts_per_break);
                v_break = NaN * ones(size(t_break));
                t_breaks = [t_breaks, t_break];
                v_breaks = [v_breaks, v_break];
                current_time = t_break(end);
            end
            % Combine the dynamic phases and breaks
            t = [t_dynamic_full(1:nr_pts_per_break+1), t_breaks, t_dynamic_full(nr_pts_per_break+2:end)];
            v = [v_dynamic_full(1:nr_pts_per_break+1), v_breaks, v_dynamic_full(nr_pts_per_break+2:end)];
        else
            % No breaks needed, use the full dynamic waveform
            t = t_dynamic_full;
            v = v_dynamic_full;
        end
    end
    time = [time, t + current_time];
    voltage = [voltage, v];
    current_time = current_time + duration;
    if i > 1
        time_act(i) = time_act(i) + time_act(i-1);
    end

end

% Plot the voltage over time

figure;

plot(time, voltage, 'LineWidth', 1.5);

xlabel('Time (s)');

ylabel('Voltage (V)');

title('User Defined Plot with Flexible Phase Order and Durations');

grid on;

ylim([0 2])

yticklabels([])

% Modify time axis to show values at the end of each phase

xticks(time_act);

xticklabels(order);

xtickangle(45);

% Check if there are more than 2 cycles for the last dynamic phase

last_cycle_idx = find(strcmp(order, 'OCV'), 1, 'last');

if last_cycle_idx < length(time_act)

    last_cycle_start = time_act(last_cycle_idx);
    last_cycle_end = time_act(last_cycle_idx + 1);
    last_cycle_duration = last_cycle_end - last_cycle_start;
    last_cycle_ticks = linspace(last_cycle_start, last_cycle_end, last_cycle_duration * 10 + 1);
    last_cycle_labels = repmat('^', 1, last_cycle_duration * 10 + 1);
    xticks([xticks(1:2), last_cycle_ticks]);
    xticklabels([xticklabels(1:2), '...', last_cycle_labels]);

end

Please let me know if you have any further questions. I really enjoyed working on this project and learned something about ticklabels how useful they can be especially for this project. Hope, no hard feelings.

Connectez-vous pour commenter.

Réponses (0)

Produits


Version

R2024a

Community Treasure Hunt

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

Start Hunting!

Translated by