How to keep plot size constant for two plots? - matlab

I'm using gramm to make two plots. I'm currently using
figure('position',[0,0,1000,1000])
So that each plot is graphed into the same size window. All of my fonts are the same size. However, plot A's X axis labels are shorter words than plot B's. This is causing matlab to shrink the size of the axis in plot B so that it can fit inside the window, which is causing plot A and B to be different sizes:
The actual images are the same size. However, the words take up more space in plot B, and so the actual plot is smaller. How can I tell matlab to keep the actual plots the same size?
Thanks in advance.

You can set the size for axis object, so change the axis size of Plot A to the axis size of plot B.
Click on Plot B to select it:
axisB = gca; % axis object for plot B
axisB.Units = 'pixels'; % or other absolute unit. Default is relative to figure
Now click on Plot A to select it:
axisA = gca;
axisA.Units = 'pixels'; % set to same unit as axisB
dHeight = axisA.Position(4) - axisB.Position(4);
axisA.Position(4) = axisB.Position(4); % set height of axisA to that of axisB
Optionally, you can reduce the figure size for plot A, so it looks better:
figA = gcf;
figA.Position(4) = figA.Position(4) - dHeight;

Related

Change Arrowhead size in quiver plot OCTAVE

I am making a simple quiver plot, but due to arrowhead size depending on the length of arrows, The arrowheads become so small that the arrow is not practically visible. I want to scale up the arrowheads to one universal size (all arrows should have the same arrowhead size in this quiver plot.
A=5;
[X,Y] = meshgrid(-3:0.5:3,-3:0.5:3);
U = A*(X.^2-Y.^2)./((X.^2+Y.^2).^2);
V = (2*A*X.*Y)./((X.^2+Y.^2).^2);
figure(1)
h = quiver(X,Y,U,V,10);
set(h,'MaxHeadSize',0.1,'AutoScale','on', 'AutoScaleFactor', 2)
This is how my plot looks:
This is how the Arrowheads should look like in size

Matlab: Plot a line over an image plot

I want to plot a line plot on top of an image plot in Matlab
First I plot the image data
figure(1); clf;
imagesc(t); colorbar
hold on;
axis tight
and then the line plot
line(ysum,y,'Color','red')
hold off;
The line plot however deletes the image and sets the background to white.
How can I plot on top of the image?
Your code isn't wrong, but it is not a minimal reproducible example, since you haven't defined t, y, ysum. When you call imagesc(t) the rows and columns will be the indices of t. In other words, it is the same as calling imagesc([1, size(t,2)], [1, size(t,1)], t). If t is small (say 10 x 10) but the elements of y,ysum are large (e.g. > 1000) then the 10 x 10 image will still be there, but it will be squished into the corner. Almost invisible.
So you need to make sure that the range of y, ysum, t line up. A quick work-around:
xidx = [min(ysum), max(ysum)];
yidx = [min(y), max(y)];
imagesc(xidx, yidx, t);

Setting axis limit for plot

I want to set the limit for X axis in this plot from 0 to 325. When i am using xlim to set the limits (commented in the code). It doesn't work properly. When i use xlim, the entire structure of plot changes. Any help will be appreciated.
figure
imagesc(transpose(all_area_for_visual));
colormap("jet")
colorbar('Ticks',0:3,'TickLabels',{'Home ','Field','Bad house','Good house'})
xlabel('Time (min)')
tickLocs = round(linspace(1,length(final_plot_mat_missing_part(2:end,1)),8));
timeVector = final_plot_mat_missing_part(2:end,1);
timeForTicks = (timeVector(tickLocs))./60;
xticks(tickLocs);
xticklabels(timeForTicks);
%xlim([0 325]);
ylabel('Car identity')
yticks(1:length(Ucolumnnames_fpm))
yticklabels([Ucolumnnames_fpm(1,:)])
If I get you right, you want to plot only part of the data in all_area_for_visual, given by a condition on tickLocs. So you should first condition the data, and then plot it:
% generate the vector of x values:
tickLocs = round(linspace(1,length(final_plot_mat_missing_part(2:end,1)),8));
% create an index vector (of logicals) that marks the columns to plot from the data matix:
validX = tickLocs(tickLocs<=325);
% plot only the relevant part of the data:
imagesc(transpose(all_area_for_visual(:,validX)));
% generate the correct ticks for the data that was plotted:
timeVector = final_plot_mat_missing_part(2:end,1);
timeForTicks = (timeVector(tickLocs(validX)))./60;
xticks(tickLocs(validX));
% here you continue with setting the labels, colormap and so on...
imagesc puts the data in little rectangles centered around integers 1:width and 1:height by default. You can specify what the x and y locations of each data point by adding two vectors to the call:
imagesc(x,y,transpose(all_area_for_visual));
where x and y are vectors with the locations along the x and y axes you want to place the data.
Note that xlim and xticks don’t change the location of the data, only the region of the axis shown, and the location of tick marks along the axis. With xticklabels you can change what is shown at each tick mark, so you can use that to “fake” the data locations, but the xlim setting still applies to the actual locations, not to the labels assigned to the ticks.
I think it is easier to plot the data in the right locations to start with. Here is an example:
% Fake your data, I'm making a small matrix here for illustration purposes
all_area_for_visual = min(floor(cumsum(rand(20,5)/2)),3);
times = linspace(0,500,20); % These are the locations along the time axis for each matrix element
car_id_names = [4,5,8,15,18]; % These are the labels to put along the y-axis
car_ids = 1:numel(car_id_names); % These are the locations to use along the y-axis
% Replicate your plot
figure
imagesc(times,car_ids,transpose(all_area_for_visual));
% ^^^ ^^^ NOTE! specifying locations
colormap("jet")
colorbar('Ticks',0:3,'TickLabels',{'Home ','Field','Bad house','Good house'})
xlabel('Time (min)')
ylabel('Car identity')
set(gca,'YTick',car_ids,'YTickLabel',car_id_names) % Combine YTICK and YTICKLABEL calls
% Now you can specify your limit, in actual time units (min)
xlim([0 325]);

Align inset in matlab plot to the right

How can I align an inset of a MATLAB plot to the top right edge of the box, like in the picture?
The example was generated with GNU R as explained in How to add an inset (subplot) to "topright" of an R plot?
Here is a way to do it:
Basically create a figure with an axes, and then add a new axis that you place to a specific position and to which you give the size you want.
Code:
clc
clear
close all
%// Dummy data
x = -20:0;
x2 = x(5:10);
%// Zoomed region to put into inset.
y = x.^2;
y2 = y(5:10);
%// Create a figure
hFig = figure(1);
%// Plot the original data
hP1 = plot(x,y);
xlabel('Original x','FontSize',18)
ylabel('Original y','FontSize',18)
hold on
%// Add an axes and set its position to where you want. Its in normalized
%// units
hAxes2 = axes('Parent',hFig,'Position',[.58 .6 .3 .3]);
%// Plot the zommed region
plot(x2,y2,'Parent',hAxes2)
%// Set the axis limits and labels
set(gca,'Xlim',[x(5) x(10)])
xlabel('Zoomed x','FontSize',16)
ylabel('Zommed y','FontSize',16)
And output:
To be fancy you could play around with the new axes position so that the outer borders coincide with the large one, but that should get you going :)

Moving MATLAB axis ticks by a half step

I'm trying to position MATLAB's ticks to line up with my grid, but I can't find a good way to offset the labels.
Also, if I run set(gca,'XTickLabel',1:10), my x tick labels end up ranging from 1 to 5. What gives?
You need to move the ticks, but get the labels before and write them back after moving:
f = figure(1)
X = randi(10,10,10);
surf(X)
view(0,90)
ax = gca;
XTick = get(ax, 'XTick')
XTickLabel = get(ax, 'XTickLabel')
set(ax,'XTick',XTick+0.5)
set(ax,'XTickLabel',XTickLabel)
YTick = get(ax, 'YTick')
YTickLabel = get(ax, 'YTickLabel')
set(ax,'YTick',YTick+0.5)
set(ax,'YTickLabel',YTickLabel)
Or if you know everything before, do it manually from the beginning:
[N,M] = size(X)
set(ax,'XTick',0.5+1:N)
set(ax,'XTickLabel',1:N)
set(ax,'YTick',0.5+1:M)
set(ax,'YTickLabel',1:M)
The marked answer works with a surf or mesh plot, however, I needed a solution which worked for a 2d plot.
This can be done by creating two axes, one to display the grid and the other to display the labels as follows
xlabels=1:1:10; %define where we want to see the labels
xgrid=0.5:1:10.5; %define where we want to see the grid
plot(xlabels,xlabels.^2); %plot a parabola as an example
set(gca,'xlim',[min(xgrid) max(xgrid)]); %set axis limits so we can see all the grid lines
set(gca,'XTickLabel',xlabels); %print the labels on this axis
axis2=copyobj(gca,gcf); %make an identical copy of the current axis and add it to the current figure
set(axis2,'Color','none'); %make the new axis transparent so we can see the plot
set(axis2,'xtick',xgrid,'XTickLabel',''); %set the tick marks to the grid, turning off labels
grid(axis2,'on'); %turn on the grid
This script displays the following figure :