MATLAB Colorbar - Same colors, scaled values - matlab

Consider the following example:
[ X, Y, Z ] = peaks( 30 );
figure( 100 );
surfc( X, Y, Z );
zlabel( 'Absolute Values' );
colormap jet;
c = colorbar( 'Location', 'EastOutside' );
ylabel( c, 'Relative Values' );
The output looks as follows:
How can I scale the ticks on the colorbar, i.e. scale the c-axis (e.g. divide the values by 100):
without changing the z values and colors on the plot
without changing the colors on the colorbar
without changing the relation between the colors on the plot, the colors on the colorbar and the z values of the plot
while still using the full range of the colorbar
In the picture above, I would like to scale the c-axis such that it shows this values for the related z:
z | c-axis
----------
8 | 8/100
6 | 6/100
4 | 4/100
. | ...
The function caxis, as I understand it, is not suited here, as it would just show the colors for a subsection of the z-axis and not for the whole z-axis.
Bonus question: How could one scale the color mapping and the colorbar as a function of X, Y and/or Z?

[ X, Y, Z ] = peaks( 30 );
figure( 101 );
surfc( X, Y, Z );
zlabel( 'Absolute Values' );
%
Z_Scl = 0.01;
Z_Bar = linspace( min(Z(:)), max(Z(:)), 10 );
%
colormap jet;
c = colorbar( 'Location', 'EastOutside', ...
'Ticks', Z_Bar, 'TickLabels', cellstr( num2str( Z_Bar(:)*Z_Scl, '%.3e' ) ) );
ylabel( c, 'Relative Values' );
For an arbitrary mapping between the z-values and the colorbar, it is possible to combine surf, contourf and contour as follows (inspired by these two great answers):
[ X, Y, Z ] = peaks( 30 ); % Generate data
CB_Z = (sin( Z/max(Z(:)) ) - cos( Z/max(Z(:)) )).^2 + X/5 - Y/7; % Generate colormap
CF_Z = min( Z(:) ); % Calculate offset for filled contour plot
CR_Z = max( Z(:) ); % Calculate offset for contour plot
%
figure( 102 ); % Create figure
clf( 102 );
hold on; grid on; grid minor; % Retain current plot and create grid
xlabel( 'x' ); % Create label for x-axis
ylabel( 'y' ); % Create label for y-axis
zlabel( 'Scaling 1' ); % Create label for z-axis
surf( X, Y, Z, CB_Z ); % Create surface plot
%
CF_H = hgtransform( 'Parent', gca ); % https://stackoverflow.com/a/24624311/8288778
contourf( X, Y, CB_Z, 20, 'Parent', CF_H ); % Create filled contour plot
set( CF_H, 'Matrix', makehgtform( 'translate', [ 0, 0, CF_Z ] ) ); % https://stackoverflow.com/a/24624311/8288778
%
CR_H = hgtransform( 'Parent', gca ); % https://stackoverflow.com/a/24624311/8288778
contour( X, Y, CB_Z, 20, 'Parent', CR_H ); % Create contour plot
set( CR_H, 'Matrix', makehgtform( 'translate', [ 0, 0, CR_Z ] ) ); % https://stackoverflow.com/a/24624311/8288778
%
colormap jet; % Set current colormap
CB_H = colorbar( 'Location', 'EastOutside' ); % Create colorbar
caxis( [ min( CB_Z(:) ), max( CB_Z(:) ) ] ); % Set the color limits for the colorbar
ylabel( CB_H, 'Scaling 2' ); % Create label for colorbar

As I wrote in your answer, I think a better choice for showing two related values is not to create a new axis for that, but to show them one near the other. Here is a suggestion:
[X,Y,Z] = peaks(30);
surfc(X,Y,Z);
zlabel('Absolute (Relative) Values');
colormap jet
Z_Scl = 0.01;
zticks = get(gca,'ZTick');
set(gca,'ZTickLabel',sprintf('%g (%g)\n',[zticks;zticks.*Z_Scl]))

Related

how can I edit grids on a battleship board to represent ships in Matlab

I am using subplot() and pcolor(zeros(7,7)); to produce the following figure for a battleship game (please see link below). Im trying to change the color of specific grids to represent ships, but I can't figure it out, so can I please get help with this, I need to for example change grids 22 and 23 in "your board" to red and have the existing figure updated, not get a new figure.
It's easiest if you set up a function to create/colour a specific square, then this is trivial, and can be recycled throughout your game. Below I've made the local function drawSquare(bs,N,player,color) which accepts a board size (bs), square number (N), a player ('top' or 'bottom'), and a colour, which can be any valid MATLAB colorspec.
Then I've made another function setup(bs) which calls this a bunch of times to create the "board" for each player.
Then you can see it's as simple as calling drawSquare( bs, 3, 'top', 'r' ); to turn the top player's square number 3 red.
Equally it's easy to call drawSquare( bs, 4, 'top', [0.6,0.5,0.5] ); to colour square 4 for that player a grey-ish tone to show something like a "hit" square in the battleships game.
figure(100);
bs = 6; % board size
% Initialise the board
setup( bs );
% Example usage colouring in specific squares
drawSquare( bs, 3, 'top', 'r' )
drawSquare( bs, 4, 'top', [0.6,0.5,0.5] );
function setup( bs )
clf; % clear the board
for ii = 1:(bs^2)
% Loop over all squares, make the base boards
drawSquare( bs, ii, 'top', 'w' );
drawSquare( bs, ii, 'bottom', 'w' );
end
% Format the plots without ticks and with titles
subplot( 2, 1, 1 );
set( gca, 'XTickLabel', '', 'YTickLabel', '', 'BoxStyle', 'full' );
title( 'Computer Board' );
subplot( 2, 1, 2 );
set( gca, 'XTickLabel', '', 'YTickLabel', '', 'BoxStyle', 'full' );
title( 'Your Board' );
end
function drawSquare( bs, N, player, color )
% sq = square size, N = square number, player = 'top' or 'bottom'
% color = valid plot colour for different square types
x = mod(N-1,bs); % x axis in grid
y = floor( (N-1)/bs ); % y axis in grid
if strcmpi( player, 'top' )
subplot( 2, 1, 1 ); % top player is subplot 1
x = bs - x; % top player square 1 is bottom-right
else
subplot( 2, 1, 2 ); % bottom player is subplot 2
y = bs - y; % bottom player square 1 is top-left
end
xp = [x, x+1, x+1, x]; % x coordinates of grid square
yp = [y, y, y+1, y+1]; % y coordinates of grid square
patch( xp, yp, color ); % use patch to make coloured square
text( x+(1/2), y+(1/2), num2str(N), 'HorizontalAlignment', 'center' );
end

How to enlarge legend symbols?

I am plotting my data as
%% Plot relative wrt to GT for each frame
XIndx_lsd = linspace(1,592, size( accu_RE_lsdSlam, 1 ) );
XIndx_my = linspace(1,592, size( accu_RE_my_method, 1 ) );
plot( XIndx_lsd, accu_RE_lsdSlam(:,5), 'r-.' )
hold on
plot( XIndx_my, accu_RE_my_method(:,5), 'b-' )
AX=legend( 'rel translation error for Kerl et al.', 'rel translation error for D-EA' );
xhand = xlabel( 'Frame#' );
yhand = ylabel( '||trans(E_i)||_2 (in mm)' );
axis( [1 600 0 16] );
set(gca,'FontSize', 78);
set(xhand,'fontsize',78)
set(yhand,'fontsize',78)
I am able to get large font size. My question is how to get a large symbol size. See marked figure below.
Using an older answer of mine, which suggests to actually replot the legend symbols,
plot( 0:10, 0:10, 'b-' ); hold on;
plot( 0:10, 10:-1:0, 'r-' ); hold on;
%// Legend Style
style = #(LineStyle,LineWidth) plot(0,0,LineStyle,'LineWidth',LineWidth,'visible','off')
AX = legend( [style('b-',20),style('r-',20)], {' Legend entry 2',' Legend entry 1'}, 'box','off' );
xlim([0 10]); ylim([0 10]);
xhand = xlabel( 'Frame#' );
yhand = ylabel( '||trans(E_i)||_2 (in mm)' );
set(gca,'FontSize', 28);
set(xhand,'fontsize',28)
set(yhand,'fontsize',28)

MATLAB - Plot multiple surface fits in one figure

I have 3 sets of 3D co-ordinates and I have fitted planes to each set. Now, I want to plot all the data points and the 3 planes in one figure.
So far, I have the following function:
function [fitresult, gof] = create_fit(xx, yy, zz, grp)
[xData, yData, zData] = prepareSurfaceData( xx, yy, zz );
ft = fittype( 'poly11' );
opts = fitoptions( ft );
opts.Lower = [-Inf -Inf -Inf];
opts.Upper = [Inf Inf Inf];
hold on;
% figure( 'Name', 'fit1' );
[fitresult, gof] = fit( [xData, yData], zData, ft, opts );
h = plot( fitresult, [xData, yData], zData);
if grp == 1
colormap(hot);
elseif grp == 2
colormap(cool);
else
colormap(grey);
end
legend( h, 'fit1', 'zz vs. xx, yy', 'Location', 'NorthEast' );
xlabel( 'xx' );
ylabel( 'yy' );
zlabel( 'zz' );
grid on
However, there are 2 problems with this:
The planes, when plotted individually are scaled according to the data points which are also plotted with them. When the planes are plotted together, they scale badly and the data points are converge to a small blob (very small scale compared to the planes)
I tried fixing the problem with axis([-0.04 0.04 -0.04 0.04 -0.04 0.04 -1 1]);, but it is hard coded and still looks a little off.
The colormap command seems to work only when called for the first time. Hence, all the planes turn out to be blue. How can I color each plane and the points fitted for that plane differently?
Is this the best way to plot multiple planes?
Edit
Here is an edited version of my initial answer. The output of plot is a two-element graphical object, so you have to call separately h(1) and h(2) to set the properties of the plane and of the data points.
Here is the code for the function:
function [fitresult, gof, h] = create_fit(xx, yy, zz, color)
[xData, yData, zData] = prepareSurfaceData( xx, yy, zz );
ft = fittype( 'poly11' );
opts = fitoptions( ft );
opts.Lower = [-Inf -Inf -Inf];
opts.Upper = [Inf Inf Inf];
hold on;
[fitresult, gof] = fit( [xData, yData], zData, ft, opts );
h = plot( fitresult, [xData, yData], zData);
set(h(1), 'FaceColor', color);
set(h(2), 'MarkerFaceColor', color, 'MarkerEdgeColor', 'k');
and here is a sample script that calls the function:
% Define sample data
N = 20;
x = rand(1,N);
y = rand(1,N);
z = rand(1,N);
% Call the function, specify color
[f1, gof1, h1] = create_fit(x, y, z, 'r');
[f2, gof2, h2] = create_fit(x, y.^10, z, 'g');
[f3, gof3, h3] = create_fit(x.^10, y, z, 'b');
% Figure adjustments
xlabel( 'xx' );
ylabel( 'yy' );
zlabel( 'zz' );
view(3)
grid on
xlim([min(x) max(x)]);
ylim([min(y) max(y)]);
zlim([min(z) max(z)]);
and the result:

Plot many horizontal Bar Plots in the same graph

I need to plot a x-y function, that shows the histograms at x-values. Something similar to the bottom plot of the next figure:
I tried to use matlab's "barh", but can't plot many in the same figure.
Any ideas?
Or, maybe displacing the origin (baseline, basevalue in barseries properties) of successive plots would work. How could I do that for barh?
thanks.
Using 'Position' of axes property
% generate "data"
m = rand( 40,10 );
[n x] = hist( m, 50 );
% the actual plotting
figure;
ma = axes('Position',[.1 .1 .8 .8] ); % "parent" axes
N = size(n,2); % number of vertical bars
for ii=1:N,
% create an axes inside the parent axes for the ii-the barh
sa = axes('Position', [0.1+(ii-1)*.8/N, 0.1, .8/N, .8]); % position the ii-th barh
barh( x, n(:,ii), 'Parent', sa);
axis off;
end

Matlab curve fitting tool, cftool, generate code function does not give the same fit

I am using Matlab's curve fitting tool, cftool, to fit a set of points which I have. The problem I am facing is that the generate code function will not give me the same fit as produced in the cftool.
This is not what I want because I want to be able to retrieve the data from the residual plot. I could also just copy the function from cftool and do it manually. But I do not understand why the generated code will not just give me the same curve fit.
The cftool session file: http://dl.dropbox.com/u/20782274/test.sfit
The generated code from Matlab:
function [fitresult, gof] = createFit1(Velocity, kWhPerkm)
%CREATEFIT1(VELOCITY,KWHPERKM)
% Create a fit.
%
% Data for 'untitled fit 3' fit:
% X Input : Velocity
% Y Output: kWhPerkm
% Output:
% fitresult : a fit object representing the fit.
% gof : structure with goodness-of fit info.
%
% See also FIT, CFIT, SFIT.
% Auto-generated by MATLAB on 02-Dec-2012 16:36:19
%% Fit: 'untitled fit 3'.
[xData, yData] = prepareCurveData( Velocity, kWhPerkm );
% Set up fittype and options.
ft = fittype( 'a/(0.008*x) + c*x^2 + d*90', 'independent', 'x', 'dependent', 'y' );
opts = fitoptions( ft );
opts.DiffMaxChange = 0.01;
opts.Display = 'Off';
opts.Lower = [-Inf -Inf -Inf];
opts.MaxFunEvals = 1000;
opts.MaxIter = 1000;
opts.StartPoint = [0 0 0];
opts.Upper = [Inf Inf Inf];
% Fit model to data.
[fitresult, gof] = fit( xData, yData, ft, opts );
% Create a figure for the plots.
figure( 'Name', 'untitled fit 3' );
% Plot fit with data.
subplot( 2, 1, 1 );
plot( fitresult, xData, yData, 'predobs' );
% Label axes
xlabel( 'Velocity' );
ylabel( 'kWhPerkm' );
grid on
% Plot residuals.
subplot( 2, 1, 2 );
plot( fitresult, xData, yData, 'residuals' );
% Label axes
xlabel( 'Velocity' );
ylabel( 'kWhPerkm' );
grid on
The curve I get with the generated code:
http://i.stack.imgur.com/65d1P.jpg
The curve I need:
http://i.stack.imgur.com/p3Egp.jpg
So does anyone know what goes wrong?
-edit-
And the Velocity and WhPerkm data file: http://dl.dropbox.com/u/20782274/data.mat
RE: I want to be able to retrieve the data from the residual plot
One way to do this is:
Select "Save to Workspace..." from the Fit menu
Ensure that "Save fit output to MATLAB struct named" is checked.
Note the name of variable. By default, it is output.
Click "OK" to send data to the MATLAB workspace.
In the MATLAB workspace, the residuals will be in output.residuals. For your example, you can plot the residuals via, e.g.,
>> plot( Velocity, output.residuals, '.' )