1

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 ?

user1640255
  • 1,224
  • 3
  • 19
  • 25
  • This really is a hack of `colorbar`. Why not create your own custom `image` object to do this? – Suever Sep 26 '16 at 18:25
  • The point is to have a dynamic colorbar next to a figure with 10 plots that change on each loop.... so how the image will help ? – user1640255 Sep 26 '16 at 18:33
  • The image would be beside the plot where the colorbar lives. That being said, can you at least show us what you expect? It's not clear. – Suever Sep 26 '16 at 19:02
  • I edit the code and if you run it is what I want. If you run the second version, with 2000 limit and plus 1000 in y then the bar sometimes appears others not. Still, I do not believe that this is the right way. i expected to have something like dB sound that you can find in some music tools... – user1640255 Sep 26 '16 at 19:06
  • The way to add another colorbar, is to add another axes: http://stackoverflow.com/a/38233971/2627163 – EBH Sep 27 '16 at 07:17
  • I create (NEW EDIT) the 2nd colorbar, but I cant make it work right. I cant also use the image version of you.... – user1640255 Sep 28 '16 at 04:31
  • The problem is that you use `colormap` to make the black bar, and there is only one `colormap` per figure, so each time you draw the bar on both colorbars. Why can't you use the `image` method? it's much more flexible. – EBH Sep 28 '16 at 05:20

3 Answers3

1

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.

dyn_colorbar

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:

dyn_colorbar3

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

left_and_right

EBH
  • 10,350
  • 3
  • 34
  • 59
  • these are great! ... just one question, if I have another y variable in the figure, and I would like to have a second colorbar, is this possible? which method is the best, the 1st or the 2nd (image) ? – user1640255 Sep 27 '16 at 00:14
  • @user1640255 to my opinion, it is more simple with this method, see my edit. – EBH Sep 27 '16 at 06:44
1

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:

dyn_colorbar

EBH
  • 10,350
  • 3
  • 34
  • 59
  • I will use possible this method, as the second is little confusing with the extra numbers in the base of image colorbar. Is it possible to use second colorbar, similar to this one, at the right or left or bottom, in which I will have another indicator to play between some limits? another y or the y(end-5) – user1640255 Sep 27 '16 at 00:17
  • possible to do that, you need to change the width, right? – user1640255 Sep 27 '16 at 01:41
  • @user1640255 have a look [here](http://stackoverflow.com/a/38233971/2627163) for a way to plot 2 colorbars on both sides – EBH Sep 27 '16 at 07:15
  • Thank you!!! ... really Pro response and detailed.... I use the first method, i will try the other (image). Thank you again! – user1640255 Sep 28 '16 at 00:48
  • please let me know if in 1st method, that I can use, I could change the limits - boundaries, of the second colorbar, if I can have second bar – user1640255 Sep 28 '16 at 01:05
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:

dyn_cb2_alt

EBH
  • 10,350
  • 3
  • 34
  • 59