Show time evolution of an hysteresis loop with color gradient

I introduced a slider in my sdof model and I'm trying to show the evolution over time of the hysteresis loop ( x axis: displacement, y axis: friction force), to do so I tried to make a 3d plot but it is not really helpful, I tried to animate the plot but it slows down the code, so I thought of using a color gradient; the problem is that most of the 'interesting' parts of the hysteresis loop happen in a relatively small intervall of the entire time vector and the colormap shows everything of the same color (almost) and it is not really clear. How can I solve this problem? I would like to manipulate the colormap in way that allows me to better represent the difference in time istants even if they are closely spaced.
Code snippet:
rel_disp = downsample((x).', 10);
FJ = downsample((kJ(j).*yJ).', 10);
n = numel(yJ);
Z_dt = t_end/n;
t = (0:Z_dt:t_end);
t(end) = [];
t = downsample(t, 10);
patch([rel_disp nan], [FJ nan], [t nan], 'Edgecolor', 'Interp', ...
'Linewidth', 0.90);
cmap = 'lines';
colormap(cmap);
colorbar;
xlabel('Displacement x [m]');
ylabel('Jenkins element force [N]');
title('Force-displacement hysteretic loop');
ax = gca;
ax.XMinorTick = 'on';
ax.YMinorTick = 'on';
ax.XMinorGrid = 'on';
ax.YMinorGrid = 'on';
if kJ(j) ~= 0
xlim([min(rel_disp) max(rel_disp)]);
ylim([min(FJ) max(FJ)]);
end
hold on

1 Comment

You forgot to attach the data and enough code to allow somebody to reproduce the plot.
As far as ideas, perhaps an inset plot that zooms into the area of interest?
Alternatively, it would take making the colormap nonlinear with the response to increase the change in color more drastically than the change in the response in order for there to be a larger color gradient. That might be visually pleasing, but it also might distort the perception of the actual data. I suppose one could manipulate the colorbar labels to match.
Although on closer observation, it appears the colorbar is log scale as is; changing to linear would amplify the changes.

Sign in to comment.

 Accepted Answer

@dbp is right (as always!): please attach a mat file with the variables necessary to run the code fragment and make the plot. These variables will inclide x, kJ, yJ, t_end, etc.
The plot you shared indicates that the hysteresis changes slowly around the beginning and the end, and it changes quickly over a narrow time range in the middle. Therefore, as @dpb says, you want to stretch the colormap around that time.
One way to do that is shown below. In example below, I made a hysteresis plot where the phase angle between x and y changes with time. The phase angle=45 degrees at t=0 and decreases to zero at t=6. The phase angle changesonly a little from t=0 to 2.5, then it changes a lot from t=2.5 to 3.5, then it changes a little from t=3.5 to 6.
I plot the data using color to indicate time. The first plot uses a standard colormap. In this plot, the hysteresis traces are all light green during the period of rapid change.
In the second plot, I adjust the colormap so most of the color change is concentrated in the time from t=2.5 to 3.5.
% hysteresis phase phi(t)=piecewise linear function of time
phi=@(t) 1-0.04*t-0.76*(t-2.5).*(t>2.5)+0.76*(t-3.5).*(t>3.5);
t=0:.001:6; % time (s)
f=10; % frequency (Hz)
x=cos(2*pi*f*t);
y=cos(2*pi*f*t+phi(t));
% Plot the data with standard colorbar for time
figure;
surface([x;x],[y;y],[zeros(size(x));zeros(size(x))],[t;t],...
FaceColor='none',EdgeColor='interp');
view(2); % 2-D plot
colormap(jet);
cb=colorbar;
cb.Label.String='Time'; % colorbar label
title('Hysteresis (linear colorbar)');
xlabel('X'); ylabel('Y');
axis equal; grid on
% Plot the data with a non-linear colorbar for time
figure
surface([x;x],[y;y],[zeros(size(x));zeros(size(x))],[t;t],...
FaceColor='none',EdgeColor='interp');
view(2); % 2-D plot
% timeNL=nonlinear monotonic time vector. delta t is small when the phase is changing quickly
% and delta t is large when phase is changing slowly
timeNL=[0:.03:2.49,2.5:.005:3.5,3.51:.03:6];
cmap=jet(length(timeNL));
% Use the nonlinear time vector to make a nonlinear colormap
cmapNL=interp1(timeNL,cmap,0:.01:6);
colormap(cmapNL);
cb=colorbar;
cb.Label.String='Time'; % colorbar label
title('Hysteresis (nonlinear colorbar)');
xlabel('X'); ylabel('Y');
axis equal; grid on
Note the difference between the two plots.

3 Comments

[Edit: I fixed a mistake in my colorbar tick labels. The fix is to define tMapInv() = inverse function to tMap(), and use it, rather than tMap, to generate the tick mark labels.]
Here is an alternative approach to the same problem. In the answer above, I created a modified clormp, cmapNL, using interp1(), and the color shown was based on the value of the time variable, t.
In this approach I will keep a linear colormap but instead of using t to choose the color, I will use tMap, which is a nonlinear mapping of t. I will also adjust the tick labels on the colorbar. The x(t), y(t) data is the same as in the example above.
% hysteresis phase phi(t)=piecewise linear function of time
phi=@(t) 1-0.04*t-0.76*(t-2.5).*(t>2.5)+0.76*(t-3.5).*(t>3.5);
t=0:.001:6; % time (s)
f=10; % frequency (Hz)
x=cos(2*pi*f*t);
y=cos(2*pi*f*t+phi(t));
% Define tMap=nonlinear mapping of t, using an inline function.
tMap=@(t) 0.2*t+4.8*(t-2.5).*(t>2.5)-4.8*(t-3.5).*(t>3.5);
% Also define the inverse function, for labelling the colorbar
tMapInv=@(t) 5*t-4.8*(t-0.5).*(t>0.5)+4.8*(t-5.5).*(t>5.5);
% tMap(t) should match the original time vector, t, at the start and finish
% (i.e. at t=0 and t=6 in this example). In between, tMap should change slowly when
% you want less color detail, and tMap should change rapidly when you want more
% color detail. The plot of t versus tMap will make this more clear.
% Plot tMap versus t and tMapInv vs. t
figure;
subplot(121), plot(t,tMap(t),'-b');
grid on; axis equal; title('tMap=nonlinear map of time')
xlabel('t'); ylabel('tMap'); xlim([0,6]); ylim([0,6])
subplot(122), plot(t,tMapInv(t),'-b');
grid on; axis equal; title('tMapInv=inverse ot tMap')
xlabel('tMap'); ylabel('tMapInv'); xlim([0,6]); ylim([0,6])
% Plot x(t) vs y(t), using tMap to specify the color
figure;
surface([x;x],[y;y],[zeros(size(x));zeros(size(x))],[tMap(t);tMap(t)],...
FaceColor='none',EdgeColor='interp');
view(2); % 2-D plot
colormap(jet);
cb=colorbar;
cb.Label.String='Time'; % colorbar label
cb.Ticks=[0:.5:6];
cb.TickLabels=tMapInv(cb.Ticks); % use tMapInv() for the labels
title('Hysteresis (nonlinear time map)');
xlabel('X'); ylabel('Y');
axis equal; grid on
Compare this plot and colorbar to the plot and colorbar in the answer I gave previously. They each have pros and cons.

Thanks a lot, awesome example and sorry for the missing datas!

@Lucrezia, you're welcome. Good luck with your work.

Sign in to comment.

More Answers (0)

Products

Community Treasure Hunt

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

Start Hunting!