I have a colorplot (from imagesc) with an alpha map. I'd like the colorbar to reflect the alpha (notice that in the image below the colormaps are the same). I found solutions online but none seem to work in R2014b.
Code is here:
subplot(2,1,1)
A = imagesc(meshgrid(0:10,0:5));
alpha(A,1)
colorbar
subplot(2,1,2)
B = imagesc(meshgrid(0:10,0:5));
alpha(B,.7)
colorbar
James
You could add a textbox with alpha on top of the colorbar. This works for later versions of MATLAB.
cb=colorbar
annotation('textbox',...
cb.Position,...
'FitBoxToText','off',...
'FaceAlpha',0.5,...
'EdgeColor',[1 1 1],...
'BackgroundColor',[1 1 1]);
In pre-R2014b MATLAB, the colorbar is itself an axis containing an image for which you can set alpha:
hb = findobj(gcf,'Type','axes','Tag','Colorbar');
hi = findobj(hb,'Type','image');
alpha(hi,0.7)
Instead of gcf, use the handles of the individual subplots.
Or save its handle when you make it:
hb = colorbar;
From R2014b on, the colorbar is creating using the new handle graphics system, where there is no longer a child image to modify. The colorbar is created internally with colorbarHGUsingMATLABClasses, which is an obfuscated .p file, so it's no clear how it's constructed.
Related
Im trying to superimpose a trimesh-plot over a image imshow using hold on. This works fine so far. I'd additionally like to display a colorbar, which works too, but unfortunately it does not adjust to the range specified by caxis, does anyone have an idea how to fix this?
This is an example output: The colourbar should display a range from 1 to z, not from 0 to 60. If we remove imshow everything works fine.
Here my MCVE:
clc;clf;clear
T = [1,2,3;3,1,4]; % triangulation
X = [0,1,1,0]*300; % grid coordinates
Y = [0,0,1,1]*300;
for z = 2:20;
clf;
imshow(imread('board.tif')) % plot image (this is a built in matlab test image)
hold on
Z = [1,1,1,z];
trisurf(T,X,Y,Z) % superimpose plot
colormap hot
caxis([1,z])
colorbar
drawnow
pause(0.5)
end
This appears to be a bug in how older versions of MATLAB handled the colorbar (it's not present with HG2). The "correct" behavior would be that if you have any objects in the current axes that use scaled values, then the colorbar should respect your clims. It seems that MATLAB is using the first child in the current axes to determine whether to respect your clims or not. imshow does not use scaled CDataMapping so colorbar simply ignores your clims.
It looks like you have three options:
Use imagesc rather than imshow
clf;
imagesc(imread('board.tif'));
axis image
hold on
Z = [1,1,1,z];
trisurf(T,X,Y,Z) % superimpose plot
colormap hot
caxis([1,z])
drawnow
colorbar
drawnow
pause(0.5)
Call imshow after you've created your trisurf object
clf;
hold on
Z = [1,1,1,z];
trisurf(T,X,Y,Z) % superimpose plot
colormap hot
him = imshow(imread('board.tif'));
caxis([1,z])
drawnow
colorbar
drawnow
pause(0.5)
Set the CDataMapping property of the image object to 'scaled' (will be ignored when displaying the image since it's RGB but it will allow the colorbar to function properly)
clf;
him = imshow(imread('board.tif'));
set(him, 'CDataMapping', 'scaled')
hold on
Z = [1,1,1,z];
trisurf(T,X,Y,Z) % superimpose plot
colormap hot
caxis([1,z])
drawnow
colorbar
drawnow
pause(0.5)
I use plotyy to put two plots in one graph:
f = figure('Color','white');
[ax,p1,p2] = plotyy(xx, yy1, xx, yy2);
ylabel(ax(1),'Phase','FontSize',18);
ylabel(ax(2),'Spectrum','FontSize',18);
set(ax,{'ycolor'},{'k';'k'});
set(p1,'LineWidth',2,'Color',[0.4940,0.1840,0.5560]);
set(p2,'LineWidth',2,'Color','red');
xlabel(ax(1),['Frequency [THz]'],'FontSize',18);
set(ax,'FontSize',14)
Figure is displayed perfectly, but when I try to save it as fig something like misaligned boxes appears.
I tried to use linkaxes, but with no result.
plotyy has been one of my favorite MATLAB functions to love to hate. It's a really useful function that I always seem to run into bugs with, to the point where I've completely stopped using it in favor of just stacking two (or more) axes objects and plotting to them separately. You can then set the Position property of the 'sub' axes to the same as your primary axes and they will stack nicely.
A functional example:
xx = linspace(-15,15,100);
yy1 = sin(xx);
yy2 = cos(xx);
f = figure('Color','white');
ax(1) = axes('Parent', f);
ax(2) = axes('Parent', f, 'Color', 'none', 'XTick', [], 'YAxisLocation', 'right');
p1 = plot(ax(1), xx, yy1);
hold(ax(2), 'on'); % Hold to preserve our axes properties set above
p2 = plot(ax(2), xx, yy2);
hold(ax(2), 'off');
ylabel(ax(1),'Phase','FontSize',18);
ylabel(ax(2),'Spectrum','FontSize',18);
set(ax,{'ycolor'},{'k';'k'});
set(p1,'LineWidth',2,'Color',[0.4940,0.1840,0.5560]);
set(p2,'LineWidth',2,'Color','red');
xlabel(ax(1),'Frequency [THz]','FontSize',18);
set(ax,'FontSize',14)
set(ax, 'ActivePositionProperty', 'position'); % Resize based on position rather than outerposition
set(ax(2), 'Position', get(ax(1), 'Position')); % Set last to account for any annotation changes
Along with stacking the axes you will also note that I have set the ActivePositionProperty to position (rather than outerposition). MATLAB resizes axes automatically when the Units property is set to Normalized, and it seems like this is the main spot where the issue is arising. On resizing, MATLAB also modifies the OuterPosition value for the second axes, causing it to resize the plot portion. The difference is small, [0 0 1 1] vs. [0 0.0371 1.0000 0.9599] in my case, but the effect is obviously very pronounced. You can use get and set to fix this, but you'll have to do it on every resize which is fairly annoying. The alternative is to resize based on the Position, which seems to alleviate the issue and is a tweak present in the R2015b implementation of plotyy. This also fixes plotyy except for cases where the window is very small, so I have left my answer with the more generic approach.
I've never seen a plot like the following (the plot in (a) ). Is it even possible?
According to the profile page of #Ander Biguri
Matlab can even make your dinner, if you know how to use it.
Which answers the question, if this is even possible ;-)
All we need is basic knowledge of the axes command - the rest is just tweaking to make it look nice. Let's have a look at it:
We'll start off by creating some sample data:
t = 100:220;
x1 = -(10*(t-130)).^2;
x2 = -(10*(t-150)).^2;
x3 = -(10*(t-170)).^2;
Then we'll create an initial figure with a white background
fig = figure(1);
set(fig,'Color','w');
Now we can create a new axes object and plot x1 on it:
ax(1) = axes('Position',[0.1,0.1,0.6,0.6]);
plot(ax(1),t,x1+10^4*rand(size(x1)),'-k',t,x1,'-r');
We'll remove the box around the axes, so only the x- and y-axes remain. Further we resize the plot, so we'll have enough space for the other two plots. We also set the color to none, i.e. transparent.
set(ax(1),'Color','none');
set(ax(1),'Box','off');
set(ax(1),'Position',[0.1,0.1,0.6,0.6]);
Now we need to create the second graph. We'll just create another axes object at a position which we like:
ax(2) = axes('Position',[0.2,0.2,0.6,0.6]);
plot(ax(2),t,x2+10^4*rand(size(x2)),'-k',t,x2,'-r');
set(ax(2),'Color','none');
set(ax(2),'Box','off');
and so on:
ax(3) = axes('Position',[0.3,0.3,0.6,0.6]);
plot(ax(3),t,x3+10^4*rand(size(x3)),'-k',t,x3,'-r');
set(ax(3),'Color','none');
set(ax(3),'Box','off');
And simple as that, we get something that doesn't even look that bad:
Using multiple waterfall plots, as Horchler suggested:
%// create some sample data
t=10:20:110;
x=0:1:200;
Y=bsxfun(#(x,t) normpdf(x,t,20),x,t.'); %//' fix the code formatting on SO!!
%// Make a colormap to to set the colour of the lines
colormap([1 0 0;0 0 0]);caxis=[0 1];
%// Plot the first set of lines (red ones)
h1=waterfall(x,t,Y,zeros(size(Y)));
set(h1,'FaceColor','none','LineWidth',2) %// tweak the properties
hold on
%// Plot the second set of lines (black lines), just the red lines with some noise
h2=waterfall(x,t,Y+0.002*(rand(size(Y))-0.5),ones(size(Y)));
set(h2,'LineWidth',2)
hold off
view([16 28])
we can get this:
I'm doing more or less the following:
figure
for ii=1:4
subplot(2,2,ii)
imshow(image(ii))
hcb = colorbar;
switch ii
case 1
colormap(myMap)
set(hcb,'YTickLabel', .. )
set(hcb,'YTick', .. )
case 2
colormap(myMap)
set(hcb,'YTickLabel', .. )
set(hcb,'YTick', .. )
case 3
colormap(myMap)
set(hcb,'YTickLabel', .. )
set(hcb,'YTick', .. )
case 4
colormap(aDifferentMap)
set(hcb,'YTickLabel', .. )
set(hcb,'YTick', .. )
end
end
What I'm facing is that calling colormap(aDifferentMap) for the fourth plot (ii=4), screws things up for the previous three plots: in my final figure all colorbars have aDifferentMap colormap, with also some problems to the YTick attribute.
If I comment out colormap(aDifferentMap) in case 4, it all works well (except for the fourth subplot, which will have a wrong colormap and no Ytickes whatsoever).
How can I deal with this? How can I set properties of subplot(2,2,4) without influencing subplots 1:3?
For Matlab 2014a and before applies the answer of Phil Goddard and you need to use e.g. freezeColors from FileExchange.
In Matlab 2014b the problem got solved with the update of the graphics engine to version HG-2. Now the colormap affects all axes in the figure, unless you set an axes colormap separately. (from doc)
figure
ax1 = subplot(2,1,1);
surf(peaks)
colormap(ax1,spring)
ax2 = subplot(2,1,2);
surf(peaks)
colormap(ax2,winter)
Colormap is a property of the figure, not the axes, so changing it for a subplot changes it for all subplots.
Have a look at Using multiple colormaps in a single figure for an example of a solution.
You can use ind2rgb if you just want to show images with different colormaps in a figure:
load flujet;
subplot(221); image(ind2rgb(X, gray(63)));
subplot(222); image(ind2rgb(X, jet(63)));
subplot(223); image(ind2rgb(X, hot(63)));
subplot(224); image(ind2rgb(X, copper(63)));
However, different colorbars still can't be shown in earlier versions of MATLAB.
Is it possible to change the color of the colorbar without changing the color of the figure?
figure_1 = figure;
j1= bar(rand(2,10),'stacked');
colormap(winter)
htx = colorbar('SouthOutside');
colormap(jet)
In particular I would like to have the object in the figures colored with the colormap winter and the colorbar following the colormap jet...is it possible to decouple the 2?
There are two FileExchange functions that I've used for this purpose with satisfactory results. freezeColors, which is mentioned in the link that #Benoit_11 gave in his comment will let you have two or more subplots in one figure with different colormaps, but the colorbars have to be difficult, and freezeColors ignores them. For that you need COLORMAP and COLORBAR utilities, and in particular cbfreeze which will fix the colorbar and keep it from changing.
So your code would look like this:
figure_1 = figure;
j1= bar(rand(2,10),'stacked');
colormap(winter)
freezeColors;
htx = colorbar('SouthOutside');
colormap(jet)
cbfreeze(htx);