Matlab colorbar indicator which dynamical change

2019-01-29 06:25发布

问题:

Running the next code I get a black bar in the colorbar that change in every loop.

If I change the limits, from 200 to 2000, and run for y= x.^2 +10*i +1000, 2nd version, then the bar sometimes appears , others not. Is anyone knows why? and how can make it work?

Is it possible to have a dynamic colorbar? i.e. if we plot a sound output, to show as colorbar the sound level in dB

EDITED:

x = 1:10;
figure;
for i = 1:10
y= x.^2 +10*i;
% y= x.^2 +10*i +1000; % 2nd version
plot(x,y,'-r'); hold on;
pause(1)
caxis([0 200]); 
% caxis([0 2000]); % 2nd version
cmap = jet(200);
% cmap = jet(2000);% 2nd version
cmap(y(end), :) = 0;
set(gcf, 'Colormap', cmap);
colorbar;
disp(y(end))
grid on;
end

thank you.

NEW EDIT:

based on the excellent answer by EBH, one supplementary question:

I am trying to add a second colobar, at left, but I cant make work both of them:

x = 1:10;
w1 = -15:15;
w2 = -1:1;
figure;
for i = 1:10

% %{
y= x.^2 +10*i +1000; %  
plot(x,y,'-r'); hold on;
pause(1)
caxis([0 2000]); %  
cmap1 = jet(2000);% 
cmap1(w1+y(end), :) = 0;
set(gcf, 'Colormap', cmap1);
h1=colorbar('eastoutside');
ylabel(h1, 'y')
disp(y(end))
%}


% %{
y2= x.^2 +5*i; %  
plot(x,y2,'-b'); hold on;
pause(1)
caxis([0 150]); 
cmap2 = jet(150);
cmap2(w2+y2(end-5), :) = 0; hold on;
cmap2(w2+y2(end), :) = 0; hold on;
set(gcf, 'Colormap', cmap2);
h2=colorbar('westoutside');
ylabel(h2, 'y2')
disp(y2(end-5))
disp(y2(end))

%}

grid on;
end

SO, can I make it work? is the problem the caxis?, and is it possible to decrease the width of both colorbar ?

回答1:

At your last comment you wanted to have 2 different colormaps on one figure. This is not so simple, as MATLAB supports only one colormap per figure, and it's a subject for another question. However, since you already asked it here I'll just post another answer.

So it goes like this:

x = 1:10;
w = -15:15;
cmap = [jet(2000); jet(2000)];

% left colorbar
lcb = subplot(1,3,1);
caxis([1 2000])
h1 = colorbar('west','Position',[0.1 0.11 0.05 0.815]);
h1.Limits = [1 1000];
h1.TickLabels = num2str(linspace(200,2000,numel(h1.Ticks)).');
ylabel(h1,'y')
axis off

% right colorbar
rcb = subplot(1,3,3);
caxis([1 150])
h2 = colorbar('east','Position',[0.85 0.11 0.05 0.815]);
h2.Limits = [76 150];
h2.TickLabels = num2str(linspace(10,150,numel(h2.Ticks)).');
ylabel(h2, 'y2')
axis off

% main axes
ax = axes;
ax.Position = [0.2 0.11 0.62 0.815];
grid on
hold on

scale = floor(2000/150);

for k = 1:10
    y = x.^2 +10*k +1000;
    y2= x.^2 +5*k;

    cmap = [jet(2000); jet(2000)];
    cmap(w+y(end),:) = 0; 
    disp(y(end))

    cmap(scale+2000+w+y2(end-5)*scale, :) = 0;
    cmap(scale+2000+w+y2(end)*scale, :) = 0;
    disp([y2(end-5) y2(end)])

    colormap(cmap)
    plot(ax,x,y,'-r',x,y2,'-b');
    pause(0.1)
end

And the result is:



回答2:

The reason you sometimes don't see black on the colorbar is it's very thin, all you have to do is add some width to it, like this w below:

x = 1:10;
w = -5:5;
for k = 1:10
    y= x.^2 +10*k +1000;
    plot(x,y,'-r');
    hold on;
    pause(1)
    caxis([0 2000]);
    cmap = jet(2000);
    cmap(w+y(end), :) = 0;
    set(gcf, 'Colormap', cmap);
    colorbar;
    disp(y(end))
    grid on;
end

and the result:



回答3:

Here is an idea of how to implement @Suever suggestion in the comments:

x = 1:10;
cb_width = 0.04;
c = sum(jet(4000),2);
c = c(1:2000);
h = imagesc(c);
h.Parent.Position(1) = 1-cb_width-0.07;
h.Parent.Position(3) = cb_width;
h.Parent.YAxisLocation = 'right';
h.Parent.XAxis.Visible = 'off';
axis xy
box off
colormap jet
ax = axes;
ax.Position(3) =  ax.Position(3) - cb_width;
grid on;
hold on;
w = -5:5; % <-- this is very important!
for k = 1:10
    h.CData = c;
    y = x.^2 +10*k +1000;
    plot(ax,x,y,'-r');
    h.CData(w+y(end),1) = nan;
    drawnow;
    disp(y(end))
    pause(1)
end

This code creates 2 axes within a figure, one is for the plot, and one for the "colorbar" which is actually an image.

Multiple colorbars

If you want to add another colorbar(s), it can be done easily, here is an example for 3:

x = 1:10;
cb_width = 0.08; % for all the colorbars together
c = sum(jet(4000),2);
% we define the colorbars area as [c nan c nan c]:
c = [c(1:2000) nan(2000,1) c(1:2000) nan(2000,1) c(1:2000)];
h = imagesc(c);
h.Parent.Position(1) = 1-cb_width-0.07;
h.Parent.Position(3) = cb_width;
h.Parent.YAxisLocation = 'right';
h.Parent.XAxis.Visible = 'off';
axis xy
box off
f = gcf;
back = f.Color;
cmap = [back; jet(2000); 0 0 0];
colormap(cmap)
% now we start to draw the data:
ax = axes;
ax.Position(3) =  ax.Position(3) - cb_width;
grid on;
hold on;
w = -5:5;
for k = 1:10
    h.CData = c;
    y = x.^2 +10*k +1000;
    z = x.^2 +15*k +500;
    t = x.^2 +30*k +700;
    plot(ax,x,y,'-r',x,z,'-.b',x,t,'--m');
    h.CData(w+y(end),1) = 2.1; % <-- left bar
    h.CData(w+z(end),3) = 2.1; % <-- middle bar
    h.CData(w+t(end),5) = 2.1; % <-- right bar
    drawnow;
    disp(y(end))
    pause(1)
end

which gives:

Left and right colorbars:

Adding another color bar on the left is a little bit more tricky:

x = 1:10;
cb_width = 0.88; % for all the colorbars together
c = sum(jet(4000),2);
% we define the colorbars area as [c nan c nan c]:
c = [c(1:2000) nan(2000,50) c(1:2000)];
h = imagesc(c);
h.Parent.Position(1) = h.Parent.Position(1)-0.07;
h.Parent.Position(3) = cb_width;
axis xy
box off
h.Parent.XAxis.Visible = 'off';
yyaxis left
h.Parent.YAxis(1).Color = [0 0 0];
yyaxis right
h.Parent.YAxis(2).Color = [0 0 0];
h.Parent.YAxis(2).Limits = h.Parent.YAxis(1).Limits;
% make the nan transparent
cmap = [1 1 1; jet(2000); 0 0 0];
colormap(cmap)
% now we start to draw the data:
ax = axes;
% ax.Position(3) =  ax.Position(3) - cb_width;
grid on;
hold on;
w = -5:5;
for k = 1:10
    h.CData = c;
    y = x.^2 +10*k +1000;
    z = x.^2 +15*k +500;
    plot(ax,x,y,'-r',x,z,'-.b',x,t,'--m');
    h.CData(w+y(end),1) = 2.1; % <-- left bar
    h.CData(w+z(end),52) = 2.1; % <-- right bar
    drawnow;
    disp(y(end))
    pause(0.2)
end