colorbar eastoutside vs westoutside - matlab

I put two colorbars in the same image using this submission on filexchange.
The position of the first colorbar is set by:
colorbar('WestOutside')
the position of the second one by:
colorbar('EastOutside')
Does anyone know why the first one is longer?
When looking at the Matlab documentation it seemed to me that they should be the same. What am I missing?
The skeleton of the code is the following:
%define coordinates of the nodes
theta=linspace(0,2*pi,33);
[x,y]=pol2cart(theta,1);
%define colormap of the links
cm = winter;
colormap(cm);
%plot the links
for ii=1:N
quiver(...)
end
%place the first colorbar
hcb=colorbar('EastOutside');
%freeze the first colorbar
cbfreeze(hcb);
%define the second colormap
cm = autumn;
colormap(cm);
%plot the dots
for ii=1:N
plot(...)
end
%place the second colorbar
hb=colorbar('EastOutside');

The key is to use two different axes. Based on your code:
%define coordinates of the nodes
theta=linspace(0,2*pi,33);
[x,y]=pol2cart(theta,1);
%plot the links
close
figure;
for ii=1:100
quiver(x,y)
end
%define colormap of the links
ax1 = gca;
colormap (ax1,winter)
%place the first colorbar
hcb=colorbar(ax1,'EastOutside');
%this is tentative, just to get the axes right position:
hb=colorbar(ax1,'WestOutside');
pos = ax1.Position;
hb.delete
% second colorbar
ax2 = axes;
colormap (ax2,autumn)
hb=colorbar(ax2,'WestOutside');
ax2.Position = pos;
axis off
ax1.Position = pos;
It creates this:
Using MATLAB 2015a.

Related

Matlab: Plot colourful line over background gray image whilst retaining colorbar information

I am using MATLAB I would like to plot a colourful trajectory on top of a grayscale png image whilst retaining the colour information of the trajectory. For example with the data below, I would like to plot Data B over Image A. Without Data B turning gray and without making the colourbar represent the grayscaled image. Any help would be greatly appreciated!
%Image A
RGB = imread('peppers.png');
I = rgb2gray(RGB);
figure
imshow(I)
hold on
%Data B
x = 1:1000;
y = x;
z = zeros(size(x));
lineColor = x;
surface([x;x], [y;y], [z;z], [lineColor;lineColor],...
'FaceColor', 'no',...
'EdgeColor', 'interp',...
'LineWidth', 8);
cc = colorbar();
Many thanks!
MATLAB doesn't seem to like to do more than one colourmap pet axes. By using hold on we're plotting both the image (gray colormap) and surface (e.g. jet colormap) to the same plot. By default from the non-RGB image in imshow the colormap is set to gray, and so it is the same for the surface plot. Trying to change the colourmap by invoking colormap('jet') changes the colormap for both the image and surface.
Seems that there have been others with the same problem:
https://uk.mathworks.com/matlabcentral/answers/194554-how-can-i-use-and-display-two-different-colormaps-on-the-same-figure
The best solution appears to be defining two seperate axes to the same figure and linking them so that positional information matches. You need to specify which axis to plot to, so imshow has been replaced with imagesc which has more flexibility.Then you can define a different colourmap to each axis. Unfortunately, the colorbar probably won't play ball everytime so you gotta fiddle with its positional information a bit.
In practice for your code:
figure
%Image A
ax1 = axes;
RGB = imread('peppers.png');
I = rgb2gray(RGB);
imagesc(ax1,I)
colormap(ax1,'gray')
%Data B
ax2 = axes;
ax2.Visible = 'off'; % make transparent
x = 1:1000;
y = x;
z = zeros(size(x));
lineColor = x;
h = surface(ax2, [x;x], [y;y], [z;z], [lineColor;lineColor],...
'FaceColor', 'no',...
'EdgeColor', 'interp',...
'LineWidth', 8);
colormap(ax2,'jet') % colourful colourmap
% Gotta reposition the colourbar, tedious bit!
% Position: [left bottom width height]
cb2 = colorbar(ax2,'Position',[.91 .11 .0375 .815]);
linkaxes([ax1,ax2]) % same positions in 1st and 2nd plot
Result:

Change the width of a subplot. There is no position property on the Line class

I have the following figure
that I created using the following code
%% figures
DateNumObs=datenum(table2array(ADCPCRUM2(1:1678,ColumnYear)),table2array(ADCPCRUM2(1:1678,ColumnMonth)),table2array(ADCPCRUM2(1:1678,ColumnDay)),table2array(ADCPCRUM2(1:1678,ColumnHour)),table2array(ADCPCRUM2(1:1678,ColumnMinutes)),table2array(ADCPCRUM2(1:1678,ColumnSeconds)));
Flipecart=permute(ecart(1:1677,:),[2,1]);
Flipecartreel=permute(ecartreel(1:1677,:),[2,1]);
bottomVel=min(min(min(Magnitude)),min(min(velocityModel*1000)));
topVel=max(max(max(Magnitude)),max(max(velocityModel*1000)));
bottomVer=min(min(Flipecart))
topVer=max(max(Flipecart))
figure
subplot(4,1,1);
FlipMag=permute(Magnitude,[2,1]);
[C,h] =contourf(DateNumObs,1:1:22,FlipMag);
datetick('x','dd/mm/yy','keeplimits','keepticks')
caxis manual
caxis([bottomVel topVel])
c=colorbar;
c.Label.String = 'Horizontal velocity(mm/s)';
xlabel('Date');
ylabel('Depth(m from bottom)');
set(h,'LineColor','none')
title('Observation');
subplot(4,1,2);
[C,h] =contourf(DateNumObs(1:1677),1:1:22,MagMatrixH1*1000);
datetick('x','dd/mm/yy','keeplimits','keepticks')
caxis manual
caxis([bottomVel topVel])
c=colorbar;
c.Label.String = 'Horizontal velocity(mm/s)';
xlabel('Date');
ylabel('Depth(m from bottom)');
set(h,'LineColor','none')
title('Model D1');
subplot(4,1,3)
% x0=10;
% y0=10;
% width=550;
% height=400
gcf=plot(DateNumObs(1:1677),Flipecart(10,:))
% set(gcf,'LineWidth',1,'position',[x0,y0,width,height]) % Part giving the error
datetick('x','dd/mm/yy','keeplimits','keepticks')
caxis manual
caxis([bottomVer topVer])
subplot(4,1,4)
c=colorbar;
plot(DateNumObs(1:1677),Flipecartreel(10,:))
datetick('x','dd/mm/yy','keeplimits','keepticks')
caxis manual
caxis([bottomVer topVer])
I am trying to got the normal plot to be the same size as the (blue) contourf plots by using the code which is commented in the code I posted. I got this code from https://nl.mathworks.com/matlabcentral/answers/65402-how-to-set-graph-size .
However, when I try to run it it gives me the following error:
Error using matlab.graphics.chart.primitive.Line/set
There is no position property on the Line class.
Error in StatisticsSOLA (line 315)
set(gcf,'LineWidth',1,'position',[x0,y0,width,height])
I also tried is it possible to change the height of a subplot? but I get the same error. How do I prevent this error and change the width of the bottom two figures?
You are trying to set the position of the axes and the linewidth of the line object in one go, but are not providing the correct handles. Furthermore, don't store the handles of the lines in gcf, since this is a reference to the currently active figure.
Instead you can do:
data = rand(100,200); % some data
fig = figure(1); clf;
% first subplot with colorbar
ax(1) = subplot(211);
imagesc(data)
c = colorbar;
% second subplot without colorbar
ax(2) = subplot(212);
p = plot(data(1,:))
% set height and width of second subplot
drawnow % needed to get right position value of ax(1) and ax(2)
ax_pos = [ax(2).Position(1:2) ax(1).Position(3:4)]; % keep ax(2)'s left and bottom position, and set same width and height as ax(1)
set(ax(2), 'Position', ax_pos)
Alternative
Sometimes it is easier to create colorbar in the second axes, and hide it. This way you don't have to set the positions of the axes yourself.
data = rand(100,200); % some data
fig = figure(1); clf;
% first subplot with colorbar
ax(1) = subplot(211);
imagesc(data)
c = colorbar;
% second subplot without colorbar
ax(2) = subplot(212);
p = plot(data(1,:))
c = colorbar; % draw useless colorbar,
c.Visible = 'off'; % and hide it
Figure should look the same:

Multiple axes for a single surf plot

I have a surf plot, in which I would like to have two y-axes. I cannot seem to find any other discussion quite like this.
The closest I got so far is:
surf(peaks);
view(0,0)
ax(1) = gca;
axPos = ax(1).Position;
ax(2) = axes('Position',axPos, 'Color', 'none','XTick',[],'ZTick',[],'YAxisLocation','right');
linkprop(ax, 'CameraPosition');
rotate3d on
% Desired plot
surf(peaks);
% Save axis
ax(1) = gca;
% Use the position of the first axis to define the new axis
pos = ax(1).Position;
pos2 = pos - [0.08 0 0 0];
ax(2) = axes('Position',pos2,'Color', 'none');
% Plot random line in 3D, just make sure your desired axis is correct
plot3(ones(length(peaks),1), 10:10:length(peaks)*10,...
ones(length(peaks),1), 'Color','none')
% Make plot, and non-desired axes, invisible
set(gca,'zcolor','none','xcolor','none','Color','none')
% Link axes
linkprop(ax, 'View');

plot in all the subplots at the same time

I have a figure with 2 subplots.
I would like to know if it's possible (and how) to draw the same plots in all the subplots at the same time.
For example in the following plot I'd like to plot (x,y) simultaneously and then proceed separately.
fig1 = figure
subplot(2,1,1)
plot(x,y)
hold on
subplot(2,1,2)
plot(x,y)
hold on
subplot(2,1,1)
plot(x,z)
subplot(2,1,2)
plot(x,k)
You can do it with set using cell arrays as follows. See the documentation for details.
subplot(2,1,1);
h1 = plot(x,y); %// get a handle to the plot
subplot(2,1,2)
h2 = plot(x,y); %// get a handle to the plot
set([h1; h2], {'xdata'}, {x1; x2}, {'ydata'}, {y1; y2})
%// new values: x1 x2 y1 y2
If you're asking because you want to plot the same plot behind say 16 subplots, then you could do it in a loop:
for k= 1:16
s(k) = subplot(4,4,k);
plot(x,y);
hold on;
end
If you just want it for 2 subplots then there is nothing wrong with your current code

Draw vertical lines on matlab spectrogram plot

Does the matlab spectrogram function lock the created figure in anyway? I want to draw vertical lines on the figure but the line function does not seem to do anything. How can I draw a line on a matlab spectrogram?
clc; clear all; close all;
[data, fs, nbits] = wavread(<INSERT WAVE FILE HERE>);
% [data, fs, nbits] = wavread('white_0.05_6sec_aud.wav');
N_data=length(data); N_frame=128; N_half=N_frame/2; N_loop=N_data/(N_half);
output=zeros(N_data,1);
hz=0:(fs/2)/N_half:(fs/2)-(fs/2)/N_half;
spectrogram(data, hanning(N_frame), N_half, N_frame, fs);
x = [6500 6500];
y = [0 5.5];
H = gca;
% set(gca, 'NextPlot', 'add');
% line(x, y);
h = line([6500, 6500], [0, 5.5]);
set(h, 'parent', handles.predicted_ax);
% view(-90,90)
% set(gca,'ydir','reverse')
%
% [y, x] = ginput(1)
% view(-90, 180);
The spectogram generates a surf and sets the view to (0,90). The surf sets the zlim to some values (dependent on the spectrogram data), and apparently, adding a line to the current plot does not change the zlim (probably because spectrogram locked the axes somehow; should be findable in edit spectrogram). Therefore, in view(0,90), the line completely disappears (rotate the plot; you'll see the line appear somewhere above the surface).
To resolve: the way you add a line defaults to the line having z-coordinates of [0 0],
which, for many spectrograms, will be above the range of the axes set by spectrogram.
Issuing
zl = zlim;
axis([xlim ylim zl(1) max(0, zl(2))])
view(0,90)
after the line should then make the line appear.
Also: in my case, the surface over which the line was hovering was mostly blue, as was the line. This doesn't help making it apparent there is a line :) I made it white, which contrasted better with the blue/yellow/red surf below.