How to rotate image and axes together on Matlab? - matlab

Code 1 where flipping vertically and/or horizontally does not affect axes();
Code 2 where proposed solution does not yield the expected output
close all; clear all; clc;
x = [5 8];
y = [3 6];
C = [0 2 4 6; 8 10 12 14; 16 18 20 22];
C2 = C(:,end:-1:1,:); %# horizontal flip
C3 = C(end:-1:1,:,:); %# vertical flip
C4 = C(end:-1:1,end:-1:1,:); %# horizontal+vertical flip
% https://stackoverflow.com/a/4010203/54964
subplot(2,2,1), imagesc(x,y,C)
subplot(2,2,2), imagesc(x,y,C2)
subplot(2,2,3), imagesc(x,y,C3)
subplot(2,2,4), imagesc(x,y,C4)
%% Rotations of axes() unsuccessfully
% https://stackoverflow.com/a/15071734/54964
figure
subplot(2,2,1), imagesc(x,y,C)
x = linspace(1, size(C, 2), numel(x)); % reverse only x
set(gca, 'XTick', x, 'XTickLabel', x)
subplot(2,2,2), imagesc(x,y,C2)
x = linspace(1, size(C, 2), numel(x)); % reverse back x
set(gca, 'XTick', x, 'XTickLabel', x) % reverse y
y = linspace(1, size(C, 1), numel(y));
set(gca, 'YTick', y, 'YTickLabel', flipud(y(:)))
subplot(2,2,3), imagesc(x,y,C3)
x = linspace(1, size(C, 2), numel(x)); % now both x,y reversed
set(gca, 'XTick', x, 'XTickLabel', x)
subplot(2,2,4), imagesc(x,y,C4)
Fig. 1 Output where axis stay untouched but images are flipped correctly,
Fig. 2 Output from attempt with moving xticks/yticks
Expected output:
Fig.1 (top-left) all correct in axes with figure
Fig.2 (top-right) y-axis correct but x-axis from 8 to 5
Fig.3 (lower-left) y-axis from 6 to 3 but x-axis correct
Fig.4 (lower-right) y-axis correct but x-axis from 3 to 6
Attempt 2
Code
% 1 start of vector 2 end of vector 3 length of vector
figure
subplot(2,2,1), imagesc(x,y,C)
x = linspace(size(C, 2), 1, numel(x)); % reverse only x
set(gca, 'XTick', x, 'XTickLabel', x)
subplot(2,2,2), imagesc(x,y,C2)
x = linspace(1, size(C, 2), numel(x)); % reverse back x
set(gca, 'XTick', x, 'XTickLabel', x)
y = linspace(size(C, 1), 1, numel(y)); % reverse y
set(gca, 'YTick', y, 'YTickLabel', flipud(y(:)))
subplot(2,2,3), imagesc(x,y,C3)
x = linspace(size(C, 2), 1, numel(x)); % now both x,y reversed
set(gca, 'XTick', x, 'XTickLabel', x)
y = linspace(1, size(C, 1), numel(y)); % reverse y
set(gca, 'YTick', y, 'YTickLabel', flipud(y(:)))
subplot(2,2,4), imagesc(x,y,C4)
Output
Error using matlab.graphics.axis.Axes/set
While setting the 'XTick' property of 'Axes':
Value must be a vector of type single or double whose values increase
Error in test_imagesc_subplot_figure (line 26)
set(gca, 'XTick', x, 'XTickLabel', x)
Eskapp's proposal
I do unsuccessfully the following but no change on Fig. 2; the first row of figures stay in the same increasing order of xaxis; I also tried instead of reverse - normal
figure
subplot(2,2,1), imagesc(x,y,C)
x = linspace(1, size(C, 2), numel(x)); % reverse only x
set(gca,'xdir','reverse')
subplot(2,2,2), imagesc(x,y,C2)
Output of Fig. 1 and Fig. 2 axis stay the same
Studying EBH's answer
Output in the y-axis label when using set(gca,'XTick',x,'XTickLabel',x, 'YTick',y,'YTickLabel',fliplr(y)) with variables y=linspace(0,180,181); x=0:0.5:10
Matlab: 2016a
OS: Debian 8.5 64 bit
Hardware: Asus Zenbook UX303UA

If I correctly understand your question, then this code does what you look for:
x = 5:8;
y = 3:6;
C = reshape(0:2:22,4,3).';
C2 = fliplr(C); % horizontal flip
C3 = flipud(C); % vertical flip
C4 = rot90(C,2); % horizontal+vertical flip
% the answer starts here:
subplot(2,2,1), imagesc(x,y,C)
set(gca,'XTick',x,'XTickLabel',x,...
'YTick',y,'YTickLabel',y)
subplot(2,2,2), imagesc(x,y,C2)
set(gca,'XTick',x,'XTickLabel',fliplr(x),...
'YTick',y,'YTickLabel',y)
subplot(2,2,3), imagesc(x,y,C3)
set(gca,'XTick',x,'XTickLabel',x,...
'YTick',y,'YTickLabel',fliplr(y))
subplot(2,2,4), imagesc(x,y,C4)
set(gca,'XTick',x,'XTickLabel',fliplr(x),...
'YTick',y,'YTickLabel',fliplr(y))
the result:
I changed you x and y from 2-element vectors, but it works also if:
x = [5 8];
y = [3 6];
BTW...
Instead of manipulating C and create C2...C4, you can just write:
subplot 221, imagesc(x,y,C)
subplot 222, imagesc(fliplr(x),y,C)
subplot 223, imagesc(x,fliplr(y),C)
subplot 224, imagesc(fliplr(x),fliplr(y),C)
and add the manipulation on the axis after each call to subplot like before.
Edit:
Using your sizes and limits of the vectors:
x = linspace(0,10,6);
y = linspace(0,180,19); % no need to plot each label
N = 3613;
C = diag(1:N)*ones(N)+rot90(diag(1:N)*ones(N)); % some arbitrary matrix
where all the rest of the code above remains the same, I get the following result:

Related

Multiple colors in the same line

I would like to plot a sine curve in Matlab. But I want it blue for the positive values and red for the negative values.
The following code just makes everything red...
x = [];
y = [];
for i = -180 : 180
x = [x i];
y = [y sin(i*pi/180)];
end
p = plot(x, y)
set(p, 'Color', 'red')
Plot 2 lines with different colours, and NaN values at the positive/negative regions
% Let's vectorise your code for efficiency too!
x = -pi:0.01:pi; % Linearly spaced x between -pi and pi
y = sin(x); % Compute sine of x
bneg = y<0; % Logical array of negative y
y_pos = y; y_pos(bneg) = NaN; % Array of only positive y
y_neg = y; y_neg(~bneg)= NaN; % Array of only negative y
figure; hold on; % Hold on for multiple plots
plot(x, y_neg, 'b'); % Blue for negative
plot(x, y_pos, 'r'); % Red for positive
Output:
Note: If you're happy with scatter plots, you don't need the NaN values. They just act to break the line so you don't get join-ups between regions. You could just do
x = -pi:0.01:pi;
y = sin(x);
bneg = y<0;
figure; hold on;
plot(x(bneg), y(bneg), 'b.');
plot(x(~bneg), y(~bneg), 'r.');
Output:
This is so clear because my points are only 0.01 apart. Further spaced points would appear more like a scatter plot.

How to set background in multiple colors in semilogy plot (MATLAB) ?

I am looking for a way to shade the background of my semilog plot in two colors.
For example, in the following image, I have am plotting three polynomials and they all are equal at x=1. I want one rectangle for x<1 region and other for x>1 region. How can I insert two such rectangles, of different colors, in background to highlight these two regions.
MWE:
x = 0.1:0.1:10;
y1 = polyval([1, 0], x); % Evaluate y = x;
y2 = polyval([1, 0, 0], x); % Evaluate y = x^2;
y3 = polyval([1, 0, 0, 0], x); % Evaluate y = x^3;
figure
semilogy(x, y1, '.k', x, y2, '.b', x, y3, '.r'); title ('Three
polynomials on a semilog y scale') xlabel('x'); ylabel('y');
legend({'y= x', 'y = x^2', 'y = x^3'}, 'Location', 'Northwest')
You can solve that using area or patch.
As pointed by #SardarUsama, there are others questions with good examples on it, however, you need to avoid to have any zeros in the area data, otherwise it will fail.
Follows the code setting one area only.
x = 0.1:0.1:10;
y1 = polyval([1, 0], x); % Evaluate y = x;
y2 = polyval([1, 0, 0], x); % Evaluate y = x^2;
y3 = polyval([1, 0, 0, 0], x); % Evaluate y = x^3;
figure
plot(x, y1, '.k', x, y2, '.b', x, y3, '.r'); %MODIFIED
hold on %ADDED
title ('Three polynomials on a semilog y scale')
set (gca, 'Yscale', 'log'); %ADDED
xlabel('x');
ylabel('y');
legend({'y= x', 'y = x^2', 'y = x^3'}, 'Location', 'Northwest')
area( [1 1 10 10],[1e-3 1e+3 1e+3 1e-3 ],'FaceColor','green','facealpha',0.3) %ADDED
The code above works for matlab after 2014b. If you have one before that, you can use the patch function (which requires some small change in the data, but uses the Facealpha option) or you can move the area to the background as i do below:
ax=get(gca,'Children'); %ADDED
set(gca,'Children',[ax(2) ax(3) ax(4) ax(1)]); %ADDED, move area to background
Note: Indeed, I missed the problem with the legend. I correct as mentioned, however for me the area was on top of the other graphs. To solve it i changed the order of the plots. If the area was with transparency, this will not be an issue.

3 x-axis in matlab plot?

I need to plot a figure with 3 x-axes. Each axis is linked to the other by a mathematical formula. I want to do this because the x value can be seen as wavelength [nm], velocity [m/s] or energy [eV] and I want the reader to not have to convert it themselves on each graph.
I searched online and only found something for 2 x-axes, but no more.
Edit: I am using version R2011a.
So it should look like this, which I (obviously) didn't create in MATLAB:
Thanks in advance!
As shown in this answer, you can create a new axes object with near-zero height, so that it is essentially just the x-axis. Be aware that all actual plots must be done on the first axes as this is the area you can see!
Demo code:
% Create some plotting data and plot
x = 0:0.1:2*pi; y = sin(x);
% Plot, can specify line attributes (like LineWidth) either
% - inline: plot(x,y,'linewidth',2)
% - after: p1 = plot(x,y); p1.LineWidth = 2;
plot(x,y);
% Get current axes object (just plotted on) and its position
ax1 = gca;
axPos = ax1.Position;
% Change the position of ax1 to make room for extra axes
% format is [left bottom width height], so moving up and making shorter here...
ax1.Position = axPos + [0 0.3 0 -0.3];
% Exactly the same as for plots (above), axes LineWidth can be changed inline or after
ax1.LineWidth = 2;
% Add two more axes objects, with small multiplier for height, and offset for bottom
ax2 = axes('position', (axPos .* [1 1 1 1e-3]) + [0 0.15 0 0], 'color', 'none', 'linewidth', 2);
ax3 = axes('position', (axPos .* [1 1 1 1e-3]) + [0 0.00 0 0], 'color', 'none', 'linewidth', 2);
% You can change the limits of the new axes using XLim
ax2.XLim = [0 10];
ax3.XLim = [100 157];
% You can label the axes using XLabel.String
ax1.XLabel.String = 'Lambda [nm]';
ax2.XLabel.String = 'Velocity [m/s]';
ax3.XLabel.String = 'Energy [eV]';
Output:
Edit:
Before the 2014b graphics changes you will need to make a couple of tweaks for getting and setting axes properties. The equivalent code would more heavily use the set command, and look something like this:
x = 0:0.1:2*pi; y = sin(x);
plot(x,y);
ax1 = findobj(gca, 'type', 'axes')
axPos = get(ax1, 'Position');
set(ax1, 'Position', axPos + [0 0.3 0 -0.3]);
set(ax1, 'LineWidth', 2);
ax2 = axes('position', (axPos .* [1 1 1 1e-3]) + [0 0.15 0 0], 'color', 'none', 'linewidth', 2);
ax3 = axes('position', (axPos .* [1 1 1 1e-3]) + [0 0.00 0 0], 'color', 'none', 'linewidth', 2);
set(ax2, 'xlim', [0 10]);
set(ax3, 'xlim', [100 157]);
axes(ax1); xlabel('Lambda [nm]');
axes(ax2); xlabel('Velocity [m/s]');
axes(ax3); xlabel('Energy [eV]');
Here's an example of how you can do this:
msx = [1 50 60 90];
msy = [0 1 3 8];
lx = 90/4*[1 2 3 4]; % Scale the data with respect to the data that will use the "primary" X-axis
ly = [0 2 8 10];
evx = 90/19*[1 7 10 19]; % Scale the data with respect to the data that will use the "primary" X-axis
evy = [0 8 16 20];
figure
a=axes('units','normalized','position',[.1 .35 .7 .6],'xlim',[0 100],'xtick',0:10:100);
plot(lx, ly)
hold on
plot(msx, msy)
hold on
plot(evx, evy)
xlabel(a,'velocity m/s')
b=axes('units','normalized','position',[.1 .21 .7 0.000001],'xlim',[0 4],'color','none', 'xtick',0:1:10);
xlabel(b,'lambda nm');
c=axes('units','normalized','position',[.1 .10 .7 0.000001],'xlim',[0 19],'color','none', 'xtick',0:1:19);
xlabel(c,'energy eV');
For the position: specified as a four-element vector of the form [left bottom width height]. The default value of [0 0 1 1] includes the whole interior of the container. (see https://de.mathworks.com/help/matlab/ref/axes-properties.html)
Output figure:

How to show the values of a matrix with its index number in graph using Matlab

I have a Matrix for example
A = [ 1 2 3; 3 4 5; 7 8 9]
I want to show the values with repect to its position Index so that one can see A(1,1) with value 1. similary for others.
I want to show values as a11, a12, a13....at the x axis and corresponding values 1, 2, 3 at the Y axis
Kindly suggest.
You could use this:
[ii, jj] = meshgrid(1:size(A,1), 1:size(A,2));
labels = strcat('(', num2str(ii(:)), ',' ,num2str(jj(:)), ')');
stem(reshape(A.',[],1)); %'// or plot, or bar, or...
set(gca, 'xtick', 1:numel(A))
set(gca, 'xticklabel', labels)
xlim([0, numel(A)+1])
To change color for each point: you can make use of hold all:
[ii, jj] = meshgrid(1:size(A,1), 1:size(A,2));
labels = strcat('(', num2str(ii(:)), ',' ,num2str(jj(:)), ')');
hold all
B = A.';
for n = 1:numel(ii)
stem(n,B(n)); %'// or plot, or bar, or...
end
set(gca, 'xtick', 1:numel(A))
set(gca, 'xticklabel', labels)
xlim([0, numel(A)+1])
Or you could define a set of colors manually and use them consecutively within the loop:
[ii, jj] = meshgrid(1:size(A,1), 1:size(A,2));
labels = strcat('(', num2str(ii(:)), ',' ,num2str(jj(:)), ')');
colors = hsv(numel(A)); %// define colors
B = A.';
hold on
for n = 1:numel(ii)
stem(n,B(n), 'color', colors(n,:)); %'// or plot, or bar, or...
end
set(gca, 'xtick', 1:numel(A))
set(gca, 'xticklabel', labels)
xlim([0, numel(A)+1])

Multi dimensional (2d better 3d) scatter-plot with different errorbars in matlab

I am trying to program scatterplot with specific errorbars. The only build in function i found is
errorbar()
but this only enables me to make a 2d plot with errorbars in y direction. What i am asking for is a method to plot this with errorbars in x and y direction.
At the end my goal is to make a 3D-scatter-plot with 3 errorbars.
Perfect would be if the resulting image would be a 3d-plot with 3d geometric shapes (coordinate x,y,z with expansion in the dimension proportional to the errorbars) as 'marker'.
I found this page while searching the internet: http://code.izzid.com/2007/08/19/How-to-make-a-3D-plot-with-errorbars-in-matlab.html
But unfortunately they use only one errorbar.
My data is set of 6 arrays each containing either the x,y or z coordinate or the specific standard derivation i want to show as errorbar.
The code you posted looks very easy to adapt to draw all three error bars. Try this (note that I adapted it also so that you can change the shape and colour etc of the plots as you normally would by using varargin, e.g. you can call plot3d_errorbars(...., '.r'):
function [h]=plot3d_errorbars(x, y, z, ex, ey, ez, varargin)
% create the standard 3d scatterplot
hold off;
h=plot3(x, y, z, varargin{:});
% looks better with large points
set(h, 'MarkerSize', 25);
hold on
% now draw the vertical errorbar for each point
for i=1:length(x)
xV = [x(i); x(i)];
yV = [y(i); y(i)];
zV = [z(i); z(i)];
xMin = x(i) + ex(i);
xMax = x(i) - ex(i);
yMin = y(i) + ey(i);
yMax = y(i) - ey(i);
zMin = z(i) + ez(i);
zMax = z(i) - ez(i);
xB = [xMin, xMax];
yB = [yMin, yMax];
zB = [zMin, zMax];
% draw error bars
h=plot3(xV, yV, zB, '-k');
set(h, 'LineWidth', 2);
h=plot3(xB, yV, zV, '-k');
set(h, 'LineWidth', 2);
h=plot3(xV, yB, zV, '-k');
set(h, 'LineWidth', 2);
end
Example of use:
x = [1, 2];
y = [1, 2];
z = [1, 2];
ex = [0.1, 0.1];
ey = [0.1, 0.5];
ez = [0.1, 0.3];
plot3d_errorbars(x, y, z, ex, ey, ez, 'or')