# How to create a custom profile in matlab plots

78 views (last 30 days)
Sachin Hegde on 24 Jul 2024 at 14:56
Edited: Umar on 25 Jul 2024 at 18:23
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 CommentsShow 1 older commentHide 1 older comment
Sachin Hegde on 25 Jul 2024 at 8:54
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 on 25 Jul 2024 at 18:17
Edited: Umar on 25 Jul 2024 at 18:23

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.

### Categories

Find more on Image Data Workflows in Help Center and File Exchange

R2024a

### Community Treasure Hunt

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

Start Hunting!