Semilogx plot issues - matlab

Quite simply, both plots are semilogx, although the range of x values isn't 10^0, 10^1, etc, as is on the bottom plot (which is what I desire), and the grid isn't what I am looking for. I need to be able to see the x intercept, which is why I need the x axis to look like that of the bottom graph but I don't know how to do it.
this is the desired graph, but I don't know how to achieve it in matlab. It's been a very long time since I've used this software
Here is the code for starters...
Exposure = [53.19, 79.79, 132.98, 212.77, 455.93];
Cure_depth = [10.88, 14.56, 19.19, 23.45, 30.36];
semilogx(Exposure,Cure_depth, '-*')
grid on

You could use the stairs function with XSale set to log.
Example:
figure;
ax = gca;
stairs(ax, Exposure, Cure_depth, '-');
set(ax, 'XScale', 'log');
grid(ax, 'on');
hold(ax, 'on');
plot(ax, Exposure, Cure_depth, '-*');
xlabel(ax, 'Exposure (mJ/cm^2)');
title(ax, 'Cure Depth vs. Exposure');
ylabel(ax, 'Cure Depth (mils)');

Related

Enlarge figure in MATLAB

I want to create figure that is enlarged, I use:
fig = figure(1); %These two lines maximize the figure dialogue
set (fig, 'Units', 'normalized', 'Position', [0,0,1,1]);
The dialogue is enlarged. What should I do if I also want the graph inside this dialogue also enlarged? Although I can use "zoom in" and "pan" in the dialogue to enlarge and reposition my graph I want this be done automatically by codes.
Thanks a lot.
Update of my question:
I am trying to plot 3D block which the value is represented by color of each small unit block:
clear; close all; clc;
fig = figure(1);
set (fig, 'Units', 'normalized', 'Position', [0,0,1,1]);
fig_color='w'; fig_colordef='white';
cMap=jet(256); %set the colomap using the "jet" scale
faceAlpha1=1;
faceAlpha2=0.65;
edgeColor1='none';
edgeColor2='none';
NumBoxX=100;%box number in x direction
NumBoxY=100;%box number in y direction
NumBoxZ=5;%box number in z direction
fid = fopen('Stress.dat','r');
datacell = textscan(fid, '%f%f%f%f%f%f%f%f%f%f%f%f%f%f');
fclose(fid);
all_data = cell2mat(datacell);
M=zeros(NumBoxX,NumBoxY,NumBoxZ);
for i=1:NumBoxX
for j=1:NumBoxY
for k=1:NumBoxZ
num=k+NumBoxZ*(j-1)+NumBoxZ*NumBoxY*(i-1);
M(i,j,k)=all_data(num,4); %the forth column of all_data is dislocation density
end
end
end
indPatch=1:numel(M);
[F,V,C]=ind2patch(indPatch,M,'v'); %Call the function ind2patch in order to plot 3D cube with color
title('\sigma_{xy}','fontsize',20);
xlabel('y','fontsize',20);ylabel('x','fontsize',20); zlabel('z','fontsize',20); hold on;
set(get(gca,'xlabel'),'Position',[5 -50 30]);
set(get(gca,'ylabel'),'Position',[5 50 -15]);
set(get(gca,'zlabel'),'Position',[64 190 -60]);
patch('Faces',F,'Vertices',V,'FaceColor','flat','CData',C,'EdgeColor','k','FaceAlpha',0.5);
axis equal; view(3); axis tight; axis vis3d; grid off;
colormap(cMap); caxis([min(M(:)) max(M(:))]);
cb = colorbar;
set(get(cb,'title'),'string','Stress (MPa)','fontsize',20);
lbpos = get(cb,'title'); % get the handle of the colorbar title
set(lbpos,'units','normalized','position',[0,1.04]);
zoom(1.9);
I maximize the dialogue, read data from a file and use a function "ind2patch" found in internet to create boxes each has a color determined by a value assigned to it. At the last part I used zoom(1.9) to enlarge it but I want to shift the whole figure without moving the colorbar.
The following is the original picture before zoomed:
https://www.dropbox.com/s/xashny3w1fwcb2f/small.jpg?dl=0
The following picture is enlarged using zoom(1.9):
https://www.dropbox.com/s/0sfqq1lgo7cm5jd/large.jpg?dl=0
MyAxes=gca;
set(MyAxes,'Units','Normalized','position',[0.1,0.1,0.8,0.8]);
Note that the position you define is with respect to your axes parent, i.e. the figure.
If the figure you want to enlarge is not the current figure, you'll have to dig in your fig object's children in order to find your axes :
MyAxes=get(fig,'Children');
set(MyAxes,'Units','Normalized','position',[0.1,0.1,0.8,0.8]);
Note that, if your figure contains several subplots (thus several axes), you'll have to loop over all of them in order to enlarge them the way you want.
UPDATE : In order to reposition your graph as would the "pan" button do, you'll have to change your axes 'xlim' and 'ylim' properties. For example, if you want to move it 5% to the right and 10% to the top :
%Get current limits
MyXLimits=get(MyAxes,'xlim'); %1x2 vector [xmin,xmax]
MyYLimits=get(MyAxes,'ylim'); %1x2 vector [ymin,ymax]
%Calculate desired limits
MyNewXLimits=[MyXLimits(1)+0.05*(MyXLimits(2)-MyXLimits(1))...
MyXLimits(2)+0.05*(MyXLimits(2)-MyXLimits(1))];
MyNewYLimits=[MyYLimits(1)+0.1*(MyYLimits(2)-MyYLimits(1))...
MyYLimits(2)+0.1*(MyYLimits(2)-MyYLimits(1))];
% Set desired limits
set(MyAxes,'xlim',MyNewXLimits);
set(MyAxes,'ylim',MyNewYLimits);
Or if you know a priori the X and Y limits you want :
%Set desired limits directly
set(MyAxes,'xlim',[Myxmin Myxmax]);
set(MyAxes,'ylim',[Myymin Myymax]);
I think you can figure out how to zoom in/zoom out by yourself, as it also involves playing with the limits of your graph.

How can I combine multipe x-axis while using the same y-axis?

I am trying to plot the wake velocity deficient behind an object at different streamwise positions (pos.1, 2 and 3) behind the object.
A rough sketch of how the graph should look like is shown below. The x-axis represents velocity and the y-axis is the coordinate normal to the flow.
How can I restart the x-axis such that the data of each position is plotted in it's own space, resembling it's actual position in the flow.
Easiest solution I think is to create all plots you need in horizontally arranged subplots, and then "beautify" according to your level of perfectionism ^_^
The "beautifications" I did in this case are:
For the axes in each subplot, switch the 'box' option off
Set the ytick to [] and color the y-axes white, of every y-axis except the leftmost one
create another axes object in the background without any axes labels, so that it appears that the subplots are really one plot
Here's the code:
%// Some bogus data
y = 0:0.1:4*pi;
x1 = sin(y);
x2 = sin(3*y);
x3 = sin(2*y).*sin(5*y);
%// Initialize figure window
figure(1), clf, hold on
%// Plot each plot on its own axes
subplot(1,3,3), hold on
plot(x3,y)
set(gca,...
'ytick' , [],...
'ycolor', 'w',...
'box' , 'off');
subplot(1,3,2)
plot(x2,y)
set(gca,...
'ytick' , [],...
'ycolor', 'w',...
'box' , 'off')
subplot(1,3,1)
plot(x1,y)
set(gca,...
'box', 'off') %// NOTE: don't kill these axes
%// Background axes
P = axes('parent', 1, 'xtick', [], 'ytick', []);
uistack(P, 'down', 10)
You could consider plotting your data on a single x-axis with an offset and changing the label of the x-axis ticks.
Consider your x-vector to be x_pos1 for the first position, your second and third would be similar but with an addition of an offset. E.g. offset = 15; x_pos2 = x_pos1+offset;
You can obtain and change your x-axis tick label by:
get(gca, 'xticklabel')
set(gca, 'xticklabel', yourLabelHere)

Overlaying two axes in a Matlab plot

I am looking for a way to overlay an x-y time series, say created with 'plot', on top of a display generated by 'contourf', with different scaling on the y-axes.
It seems that the typical way to do this in the case of two x-y plots is to use the built-in function 'plotyy', which can even be driven by functions other than 'plot' (such as 'loglog') as long as the input arguments remain the same (x,y). However, since in my case contourf requires three input arguments, 'plotyy' seems to not be applicable. Here is some sample code describing what I would like to do:
x1 = 1:1:50;
y1 = 1:1:10;
temp_data = rand(10,50);
y2 = rand(50,1)*20;
figure; hold on;
contourf(x1,y1,temp_data);
colormap('gray');
plot(x1,y2,'r-');
Ideally, I would like the timeseries (x1,y2) to have its own y-axes displayed on the right, and be scaled to the same vertical extent as the contourf plot.
Thanks for your time.
I don't think there's a "clean" way to do this, but you can fake it by overlaying two axes over each other.
x1 = 1:1:50;
y1 = 1:1:10;
temp_data = rand(10,50);
y2 = rand(50,1)*20;
figure;
contourf(x1, y1, temp_data);
colormap('gray');
h_ax = gca;
h_ax_line = axes('position', get(h_ax, 'position')); % Create a new axes in the same position as the first one, overlaid on top
plot(x1,y2,'r-');
set(h_ax_line, 'YAxisLocation', 'right', 'xlim', get(h_ax, 'xlim'), 'color', 'none'); % Put the new axes' y labels on the right, set the x limits the same as the original axes', and make the background transparent
ylabel(h_ax, 'Contour y-values');
ylabel(h_ax_line, 'Line y-values');
In fact, this "plot overlay" is almost definitely what the plotyy function does internally.
Here's example output (I increased the font size for legibility):

Adding an x axis label with 2 y axis labels

I can add 2 y-axis to a octave/matlab plot but when I try and add the x-axis at the bottom of the plot with xlabel('Frequency in Hz') it doesn't show up
[ax h1 h2]=plotyy(xx,yy,xx,yy2); %plot two y axes and 1 x-axis
axes(ax(1)); ylabel('Phase Angle in degrees');
axes(ax(2)); ylabel('Amplitude');
Anybody know how to fix this so the x-axis will also show up
I'm using octave 3.2.4 / matlab
Make sure to call xlabel() after referencing one of the specific axes on the plot. You just need to do it once, but because of the double axis, invoking x-label outside of a specific axis context won't work. The following works for me just fine in Octave 3.2.4.
xx = [1,2,3];
yy = [10,11,12];
yy2 = [-10,-11,-12];
[ax h1 h2]=plotyy(xx,yy,xx,yy2);
axes(ax(1)); xlabel('Frequency in Hz'); ylabel('Phase Angle in degrees');
axes(ax(2)); ylabel('Amplitude');
In order to add a label (either xlabel or ylabel) to certain axes you can also pass this axes reference as first argument of the command call. This way you will also guarantee that you are on the right context as #EMS pointed out.
xx = [1,2,3];
yy = [10,11,12];
yy2 = [-10,-11,-12];
[ax h1 h2]=plotyy(xx,yy,xx,yy2);
xlabel(ax(1),'Frequency in Hz'); ylabel(ax(1),'Phase Angle in degrees');
ylabel(ax(2),'Amplitude');
This is also better in terms of performance, as in case you call axes several times, you will see how everything slows considerably down.

Plotting a subplot on top of another plot in Matlab

I need to plot several plots along a sloped line at different positions.
For example, if I:
plot(0:200,'k');
plotpts = 5:5:200;
I would like to be able to plot a smaller plot at each of my plotpts on top of the original 0:200 line.
I know you can use hold on and plot over top that way, but I need to change my origin each time. Does anyone have any suggestions? I would really like to stay in matlab. Thanks!
Here is a flexible way I usually do it:
plot(1:10, 'k')
plotpts = 2:2:8;
mainbox = get(gca, 'Position');
xlims = get(gca, 'XLim');
ylims = get(gca, 'Ylim');
for i=1:length(plotpts)
originx = mainbox(1) + (plotpts(i) - xlims(1)) * (mainbox(3)) / (xlims(2) - xlims(1));
originy = mainbox(2) + (plotpts(i) - ylims(1)) * (mainbox(4)) / (ylims(2) - ylims(1));
axes('position', [originx originy 0.1 0.1], 'Color', 'none')
% Do some plotting here...
end
It's quite a bit of work, but you probably want to use the axes command. A figure window can host any number of axes, where each axes has it's own position, data, annotations, color etc.
The most difficult thing for the application you describe is that each axis position needs to be defined in the coordinate frame of the underlying figure, which means that some math may be required to create the illusion that the axis is correctly positioned within a parent axes/
For example, if you first create a simple plot
figure(1234); clf;
plot(1:10, rand(1,10),'.k-','linewidth',5);
xlim([1 10]);
ylim([0 1]);
set(gca,'color','y'); %This just helps demonstrate the next steps
You can place another axis directly on top of the first, and then
ha = axes('position',[.2 .3 .1 .1])
plot(linspace(0,2*pi,100), sin(linspace(0,2*pi,100)), 'b-')
xlim([0 2*pi])
You can adjust the the properties of the inset axis to suit your particular needs, for example
set(ha,'color','none'); %A transparent axis
set(ha,'xtick',[],'ytick',[]); %Remove tick labels
title(ha,'This is an inset plot')
Is the command subplot not what you're looking for?