Making the color, for each function that is plotted with a loop, correspond to the color bar .

21 views (last 30 days)
So I am plotting an iterating function for each parameter "a" between a range of values (in this case it's -1.6 to 1.6).
k=20; niter=2^k; % 2^k total iterations
x=zeros(1,niter); y=zeros(1,niter); % filling empty arrays
x1=zeros(1,niter); y1=zeros(1,niter);
da=0.2;
amin=-1.6; amax=1.6; b=0.3; % a=real and b=imaginary parts of c
for a = amin:da:amax
disp(a)
x(1)=real(0.5+sqrt(0.25-(a+i*b))); % IC
y(1)=imag(0.5+sqrt(0.25-(a+i*b))); % IC
for n=1:niter % iterate
x1=x(n); y1=y(n);
u=sqrt((x1-a)^2+(y1-b)^2)/2; v=(x1-a)/2;
u1=sqrt(u+v); v1=sqrt(u-v);
x(n+1)=u1; y(n+1)=v1;
if y(n)<b
y(n+1)=-y(n+1);
end
if rand < .5 % flip a coin
x(n+1)=-u1; y(n+1)=-y(n+1);
end
end
plot(x,y,'k.','MarkerSize',2)
hold on;
end
% PLOT
fsize=15; fsizea=30; % font size of axis and title labels
xlim([-1.6 1.6]); ylim([-1.6 1.6]);
axis square
xlabel('Real(z)','FontSize',fsizea)
ylabel('Imaginary(z)','FontSize',fsizea)
set(gca,'xtick',[-1.6:0.4:1.6],'FontSize',fsize)
set(gca,'ytick',[-1.2:0.4:1.2],'FontSize',fsize)
title(sprintf('Julia Set for c = %s<a<%s + %s i',num2str(amin,'%1.1d'),num2str(amax,'%1.1d'),num2str(b,'%1.1d')),'FontSize',fsizea)
rect = [0,0,260*2.0,260*1.7];
set(gcf,'Position',rect);
set(gcf,'PaperPositionMode','auto');
c = colorbar;
caxis([amin amax])
c.Label.String = 'a';
What I want is to have the colorbar represent the range of values of "a", and to have each function that is plotted for each value of "a" to match the color in the colorbar for that value of "a". Here is what the output looks like so far. (This is the default colorbar with the default colors by the way)

Accepted Answer

Cris LaPierre
Cris LaPierre on 4 Apr 2019
Edited: Cris LaPierre on 4 Apr 2019
There are a couple things to be careful of. First, there is no connection between the colorbar and line series color. The colorbar typically indicates the Z value in an X,Y,Z plot. Not that it can't be done, but just adding a colorbar does not do it automatically. Normally this is done with a legend instead.
Next, caxis only sets the scale of the colorbar. Values of Z that exceed the min and max value are shown in the min or max color (respectively). When there are no Z values it is connected to, it does nothing. I see what you are trying to do, but this won't do that. You instead need to set the colorbar ticks and labels (similar to axis ticks and labels).
h = colorbar;
tk = linspace(0,1,2*length(a)+1);
set(h, 'YTick',tk(2:2:end),'YTickLabel', a');
When plotting multiple series, MATLAB cycles through a specified ColorOrder. The default ColorOrder only has 7 unique colors. Where you have 17 different values of a, you need to modify the axes colormap to include at least 17 unique colors in ColorOrder. The challenge is that it's very difficult to generate 17 unique colors that can be easily distinguished. The link will show you the builtin ones. The code below shows you how to use a predefined colormap to do this. You can of course define your own colors instead.
map = jet(length(a));
axes('ColorOrder',map,'NextPlot','replacechildren')
The other thing to be aware of is that, when plotting a matrix, MATLAB will automatically treat each column as a series, and will therefore plot each in a different color following the colors specified in the ColorOrder. MATLAB is great at handling matrices, which means you can speed up your code by iterating for all values of a at the same time, creating x and y as matrices instead of vectors where each column corresponds to a value of a.
Put it all together, and here is the code I would recommend. I have reorganized your code a little.
k=20; niter=2^k; % 2^k total iterations
da=0.2;
amin=-1.6;
amax=1.6;
b=0.3; % a=real and b=imaginary parts of c
a = amin:da:amax;
x=zeros(niter+1,length(a)); y=zeros(niter+1,length(a)); % filling empty arrays
x(1,:)=real(0.5+sqrt(0.25-(a+i*b))); % IC
y(1,:)=imag(0.5+sqrt(0.25-(a+i*b))); % IC
for n=1:niter % iterate
x1=x(n,:);
y1=y(n,:);
u=sqrt((x1-a).^2+(y1-b).^2)/2;
v=(x1-a)/2;
u1=sqrt(u+v);
v1=sqrt(u-v);
x(n+1,:)=u1;
% Use logical indexing here instead of an if statement to do for all values of a at once
tmp1 = ones(1,length(a));
tmp1(y1<b)=-1;
y(n+1,:)=v1.*tmp1;
% Use logical indexing here instead of an if statement to do for all values of a at once
tmp2 = ones(1,length(a));
tmp2(rand(1,length(a))<.5)=-1; % flip a coin
x(n+1,:)=u1.*tmp2;
y(n+1,:)=y(n+1,:).*tmp2;
end
% Specify axes ColorOrder
map = jet(length(a));
axes('ColorOrder',map,'NextPlot','replacechildren')
plot(x,y,'.','MarkerSize',2)
% Create discrete colorbar
colormap(map)
h = colorbar;
tk = linspace(0,1,2*length(a)+1);
set(h, 'YTick',tk(2:2:end),'YTickLabel', a');
h.Label.String = 'a';
% PLOT
fsize=15; fsizea=30; % font size of axis and title labels
xlim([-1.6 1.6]); ylim([-1.6 1.6]);
axis square
xlabel('Real(z)','FontSize',fsizea)
ylabel('Imaginary(z)','FontSize',fsizea)
set(gca,'xtick',[-1.6:0.4:1.6],'FontSize',fsize)
set(gca,'ytick',[-1.2:0.4:1.2],'FontSize',fsize)
title(sprintf('Julia Set for c = %s<a<%s + %s i',num2str(amin,'%1.1d'),num2str(amax,'%1.1d'),num2str(b,'%1.1d')),'FontSize',fsizea)
rect = [0,0,260*2.0,260*1.7];
set(gcf,'Position',rect);
set(gcf,'PaperPositionMode','auto');
As a side comment, you could also use a legend, though your markersize is too small to really be helpful in this case. This is the code you could use instead of all the colorbar code above.
legend(cellstr(num2str(a')),'Location','eastoutside')

More Answers (0)

Categories

Find more on Colormaps in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!