I'm always see this kind of graph in XRD plot:
and i'm wondering how they do that?, if you have different XRD plot and assuming having the same y axis, can matlab do this? thanks.
Here is a way to do it.You can customize it as you want, but this should hopefully get you going.
First create an axes and change its position/size inside the figure, shifting it upward to make room for the 2nd axes as well as removing the x and y labels that you don't want. Then create a 2nd axes with specified position/size to make it fit below the 1st one.
Sample code:
clear
clc
%// Generate dummy data
x = 1:2:100;
y1 = rand(1,numel(x));
figure;
%// Make an axes and set its position
haxes1 = axes('Position',[.1 .1 .8 .7],'Color',[1 1 1])
%// Plot 1st curve
plot(x,y1,'Parent',haxes1)
%// Remove box and labels
box off
set(gca,'XTickLabel','','XTick',[],'YTick',[])
hold on
%// Get current axes position. You set it so you could get the parameters
%// directly as well.
axes1Pos = get(gca,'Position');
%// Shift 1st axes upward
set(gca,'Position',[axes1Pos(1) 2.6*axes1Pos(2) axes1Pos(3) axes1Pos(4)])
%// Change the poisition/size of the 2nd axes to fit below the 1st one
haxes2 = axes('Position',[axes1Pos(1) axes1Pos(2)/2.5 axes1Pos(3) axes1Pos(4)/2.5]) ;
%// Use linspace to generate colored points to use with scatter.
c = linspace(1,10,length(x));
%// Add 2nd plot and keep only x label
scatter(x,rand(1,numel(x)),40,c,'filled')
set(gca,'YTick',[])
box off
%// Place a ylabel for both axes
text(-4, 1.7,'Super nice y label','rotation',90,'FontSize',16,'HorizontalAlignment','center')
Sample output:
There are other ways to do this as well.
Hope that helps!
Related
Here is a simple MATLAB code. How to control the default distance between ticks of the Y axis? I want to make it smaller to fit in my paper. Hint: I update the post with 2 picture that shows what I mean (they are the same but the distance between the y axis ticks is smaller in one picture that the other.
x = linspace(-10,10,200);
y = sin(4*x)./exp(x);
plot(x,y)
xlim([0 10])
ylim([-0.4 0.8])
You can control the tick by using the gca object of the plot. Here is an example for xtick. Change 'xtick' to 'ytick':
plot(x,y);
set(gca, 'xtick', [-10:2:10]);
If you want to change the x-axis tick labels with new labels, then you can change the values of the labels as follows:
% specify the ticks first where you want to change
xticks([0 2 4 6 8])
% change the corresponding labels to the required ones
xticklabels({'-1', '-2', '-3', '-4', '-5'})
You can modify the height of the graph, maintaining the number and values of the tick marks, which makes the distance between tick marks smaller.
To do so, set the figure window’s 'Position' property (this is equivalent to dragging the edges of the window to make the figure smaller), and setting the locations of the tick marks manually to prevent MATLAB from reducing their number. For example:
h = gcf; % figure handle
a = gca; % axes handle
ticks = get(a,'YTick');
pos = get(h,'Position');
pos(4) = pos(4) * 0.75; # reduce the size
set(h,'Position',pos);
set(a,'YTick',ticks)
You should also note the PaperPosition, PaperSize and other Paper... properties of the figure, as they are used when printing (also to file). You might want to manually set those properties before creating a PDF or EPS from the graph.
Here is even a simpler way then what #Cris suggested:
ax = axes;
ax.YTickMode = 'manual';
ax.Position(4) = ax.Position(4)*0.75;
by setting the YTickMode to manual you prevent Matlab from updating the ticks upon resizing of the axes. Then you change the hight of the axes by setting the position property directly.
I have graphed a Bode plot for my transfer function, and I was wondering if there is some way to insert either horizontal or vertical lines to show a specific value for the gain/phase angle or frequency?
I have found with the following code I can draw a horizontal line on the phase angle graph:
x = linspace(10^-1,10^2,100);
for bleh = 1:length(x)
y(bleh) = -30.9638;
end
bode(num, den)
hold on
plot(x,y)
But this does not seem to apply in the gain graph, nor does my limited knowledge (and only way that makes sense to me) of vertical lines. I tried:
y1 = get(gca,'ylim');
w1 = 1.2;
bode(num, den)
hold on
plot(x,y,[w1 w1],y1)
But I only get the one horizontal line as was done from the above code.
Is this a possibility?
(Using R2017a, if that matters.)
I'm not sure I've understood you question, nevertheless, I propose the following.
When there are more one axes in a figure, as it is the case of the bode diagram, if you want to add something in a specific axes (or in all) you have to specify, in the call to plot the handle of the axes.
So, to add lines in the bode diagram, you have first to identify the handles of the two axes: you can do it in, at least two way:
using the findobj function: ax=findobj(gcf,'type','axes')
extract them as the Children of the figure: ax=get(gcf,'children')
Once you have the handles of the axes, you can get their XLim and YLim that you can use to limit the extent of the line you want to add.
In the following example, I've used the above proposed approach to add two lines in each graph.
The horizontal and vertical lines are added in the middle point of the X and Y axes (problably this point does not have a relevant meaning, but it is ... just an example).
% Define a transfer function
H = tf([1 0.1 7.5],[1 0.12 9 0 0]);
% PLot the bode diagram
bode(H)
% Get the handles of the axes
ax=findobj(gcf,'type','axes')
phase_ax=ax(1)
mag_ax=ax(2)
% Get the X axis limits (it is the same for both the plot
ax_xlim=phase_ax.XLim
% Get the Y axis limits
phase_ylim=phase_ax.YLim
mag_ylim=mag_ax.YLim
%
% Define some points to be used in the plot
% middle point of the X and Y axes of the two plots
%
mid_x=(ax_xlim(1)+ax_xlim(2))/2
mid_phase_y=(phase_ylim(1)+phase_ylim(2))/2
mid_mag_y=(mag_ylim(1)+mag_ylim(2))/2
% Set hold to on to add the line
hold(phase_ax,'on')
% Add a vertical line in the Phase plot
plot(phase_ax,[mid_x mid_x],[phase_ylim(1) phase_ylim(2)])
% Add an horizontal line in the Phase plot
plot(phase_ax,[ax_xlim(1), ax_xlim(2)],[mid_phase_y mid_phase_y])
% Set hold to on to add the line
hold(mag_ax,'on')
% Add a vertical line in the Magnitide plot
plot(mag_ax,[mid_x mid_x],[mag_ylim(1) mag_ylim(2)])
% Add an Horizontal line in the Magnitide plot
plot(mag_ax,[ax_xlim(1), ax_xlim(2)],[mid_mag_y mid_mag_y])
Hope this helps,
Qapla'
I want my graph to fixed axes and also plot the data one by one. Everything is already known, however if i use hold off to remove the first set of data, it also forgets the limits on the axes and automatically assigns new limits for the second set of data.
Is it somehow possible to keep the axes the same for each time a separate data piece is plotted in the same figure?
code for now is:
figure(4)
grid on
axis([xL yL zL])
for j = 1:n % n is amount of data sets
for i = 1:2 % two items drawn per data set
*plot data*
hold on
end
%This part has to be done every iteration again in order to make it work now
axis([xL yL zL])
xlabel = ...
ylabel
zlabel
title
pause(tstop)
hold off
end
after some searching the only relevant topic i found was; Matlab: Plot a subplot with hold on and hold off in a loop without always calling xlabel, ylabel, xlim, etc
However i do not understand it at all. It uses a parent figure, replacechildren, nextplot and such which i am not familiar with and also cant find much information about.
Here's an example that can be easily adapted to your needs:
xlim([0 10]) %// set x-axis limits
ylim([0 10]) %// set y-axis limits
set(gca,'nextplot','replacechildren') %// prevent axis limits from changing with
%// each new plot
plot(3:8,3:8); %// note axis limits are kept as [0 10]
pause(1)
plot(5:7,5:7); %// note axis limits are kept as [0 10]
I struggle a little bit with overlapping axis numbers of the y and x axis like it is shown in the image. I'd like to keep the size of the numbers and therefore think that simply shifting the numbers away from the axis itself would be an appropriate way to handle this issue.
Is there a possibility to do that?
Thanks in advance,
Joe
Here is a little workaround using text annotations. Basically you clear the current XTick labels and replace them with similar labels, but you can specify the distance from the axis:
clc
clear
close all
x = 1:20;
hPlot = plot(x,sin(x));
set(gca,'xaxisLocation','top');
set(gca,'XTickLabel',[]); %// Clear current XTickLabel
ylim = get(gca,'YLim'); %// Get y limit of the plot to place your text annotations.
for k = 2:2:20
text(k,ylim(2)+0.1,num2str(k),'HorizontalAlignment','Center') %// Play with the 'ylim(1) -0.1' to place the label as you wish.
end
Giving this:
Of course now it's exaggerated and you can do the same for the y axis if you want (using the 'XLim' property of the current axis,gca).
How can I make plots in MATLAB like in below?
I won't need labels, so you can ignore them. I tried using normal 2D plot, by giving 0 to y parameter for each data points. It does help, but most of the plot remains empty/white and I don't want that.
How can I solve this problem?
Edit:
This is how I plot(playing with values of ylim does not help):
hold on
for i=1:120
if genders(v_labels(i)) == CLASS_WOMAN
plot(v_images_lda(i,:) * w_lda,0,'r*');
else
plot(v_images_lda(i,:) * w_lda,0,'b.');
end
end
title('LDA 1D Plot');
ylim([-0.2 0.2]);
hold off
One way to do this would be to adjust the 'XLim', 'YLim', and 'DataAspectRatio' properties of the axes so that it renders as essentially a single line. Here's an example:
data1 = rand(1,20)./2; %# Sample data set 1
data2 = 0.3+rand(1,20)./2; %# Sample data set 2
hAxes = axes('NextPlot','add',... %# Add subsequent plots to the axes,
'DataAspectRatio',[1 1 1],... %# match the scaling of each axis,
'XLim',[0 1],... %# set the x axis limit,
'YLim',[0 eps],... %# set the y axis limit (tiny!),
'Color','none'); %# and don't use a background color
plot(data1,0,'r*','MarkerSize',10); %# Plot data set 1
plot(data2,0,'b.','MarkerSize',10); %# Plot data set 2
And you will get the following plot:
Here's one way to reproduce your figure using dsxy2figxy and annotate. dsxy2figxy can be hard to find the first time, as it is not really in your path. It is part of the MATLAB package and is provided in the example functions. You can reach it by searching for it in the help docs and once you find it, open it and save it to a folder in your path.
h1=figure(1);clf
subplot(4,1,1);
hold on
xlim([0.2,1]);ylim([-1,1])
%arrow
[arrowX,arrowY]=dsxy2figxy([0.2,1],[0,0]);
annotation('arrow',arrowX,arrowY)
%crosses
x=[0.3,0.4,0.6,0.7,0.75];
plot(x,0,'kx','markersize',10)
%pipes
p=[0.5,0.65];
text(p,[0,0],'$$\vert$$','interpreter','latex')
%text
text([0.25,0.5,0.65],[1,-1,-1]/2,{'$$d_i$$','E[d]','$$\theta$$'},'interpreter','latex')
axis off
print('-depsc','arrowFigure')
This will produce the following figure:
This is sort of a hackish way to do it, as I've tricked MATLAB into printing just one subplot. All rasterized formats (jpeg, png, etc) will not give you the same result, as they'll all print the entire figure including where the non-declared subplots should've been. So to get this effect, it has to be an eps, and it works with it because eps uses much tighter bounding boxes... so all the meaningless whitespace is trimmed. You can then convert this to any other format you want.
Ok so the closest I have come to solving this is the following
hax = gca();
hold on
for i=1:120
if genders(v_labels(i)) == CLASS_WOMAN
plot(v_images_lda(i,:) * w_lda,0,'r*');
else
plot(v_images_lda(i,:) * w_lda,0,'b.');
end
end
set(hax, 'visible', 'off');
hax2 = axes();
set(hax2, 'color', 'none', 'ytick', [], 'ycolor', get(gcf, 'color');
pos = get(hax, 'position');
set(hax2, 'position', [pos(1), pos(2)+0.5*pos(4), pos(3), 0.5*pos(4)]);
title('LDA 1D Plot');
hold off
So in short, I hid the original axis and created a new one located at 0 of the original axis, and as I couldn't remove the y axis completely I set it's color to the background color of the figure.
You can then decide if you also want to play with the tick marks of the x-axis.
Hope this helps!
Very naive trick but a useful one.
Plot in 2d using matlab plot function. Then using edit figure properties compress it to whichever axis you need a 1D plot on !! Hope that helps :)