I try to put a marker on a candle plot of Matlab.
But the marker is placed under the candle, and the marker can't be seen if it is too small.
I tried to use uistack to reorder the layers, but the marker is still placed behind the candle body.
load disney;
candle(dis_HIGH(end-20:end), dis_LOW(end-20:end), dis_CLOSE(end-20:end),...
dis_OPEN(end-20:end), 'b');
hold on;
markers = plot(2,20.4,'r^','MarkerFaceColor','r', 'MarkerSize',15);
uistack(markers,'top');
hold off;
How to make the marker to be in front of the candle?
You can circumvent this issue by doing the following:
1) Add a new transparent axes at the same position than the existing one.
2) Make its NextPlot property set to add.
3) Adjust its limits to fit with that of the axes generated by the candle plot.
So in code this looks like this:
clear all
clc
close all
load disney;
candle(dis_HIGH(end-20:end), dis_LOW(end-20:end), dis_CLOSE(end-20:end),...
dis_OPEN(end-20:end), 'b');
%//======================
%// Get current axes
Axes1 = gca;
%// Get the current limits
Axes1XLim = get(gca,'XLim');
Axes1YLim = get(gca,'YLim');
%// Create new axes
hold on
NewAxes = axes('Position',get(gca,'Position'),'Color','none','XTick',get(Axes1,'XTick'),'YTick',get(Axes1,'YTick'),'NextPlot','add')
%// Plot your data on new axes
m = plot(NewAxes,2,20.4,'r^','MarkerFaceColor','r', 'MarkerSize',15);
%// Adjust its limits
xlim(Axes1XLim)
ylim(Axes1YLim)
And the output:
Related
I have I have a data file which has 3 columns, 1st column is the field for the data, or you can say different index. 2nd column is the x-axis data, and the 3rd column is the y-axis data. Now I have similar data files for different variables like 8 files. I want to plot all the graph in one figure in MATLAB. For my problem, I am showing only one subplot. This subplot data file should plot 5 "line plots" for 5 indexes (1st column). But when I plot it as subplot it shows only 1 plot. here is my code in the below:
% open Zdiff Odd Mode data file
fid = fopen('Data_test.txt');
% Read data in from csv file
readData = textscan(fid,'%f %f %f','Headerlines',1,'Delimiter',',');
fclose(fid);
% Extract data from readData
index_Data = readData{1,1}(:,1);
% Identify the unique indices
uni_idx=unique(index_Data);
xData = readData{1,2}(:,1);
yData = readData{1,3}(:,1);
% Plot Data
f = figure;
%Top Title for all the subplots
p = uipanel('Parent',f,'BorderType','none');
p.Title = 'Electrical Characteristics';
p.TitlePosition = 'centertop';
p.FontSize = 14;
p.FontWeight = 'bold';
cla; hold on; grid on, box on;
ax1 = subplot(2,4,1,'Parent',p);
% Loop over the indices to plot the corresponding data
for i=1:length(uni_idx)
idx=find(index_Data == uni_idx(i));
plot(xData(idx,1),yData(idx,1))
end
The plot results like below:
When I plot the data as a full figure, the plot is perfect. But as I have lots of data to plot in one figure as subplots, I need to know what is wrong in my subplot code.
Here is my code for the whole figure of the data without the subplot
Before plotting code it is same as before:
% Plot Data
f1 = figure(1);
cla; hold on; grid on;
% Loop over the indices to plot the corresponding data
for i=1:length(uni_idx)
idx=find(index_Data == uni_idx(i));
plot(xData(idx,1),yData(idx,1))
end
The resulting figure is below:
What is wrong with my plotting code in the subplot? Can anyone help me out?
This is your sequence of commands, and what they do:
f = figure;
Creates an empty figure, there are no axes yet defined here.
cla
Clears the current axes, since there is no current axes, it creates one.
hold on
Sets the "hold" property on the current axes
grid on, box on
Sets some other properties of the current axes
ax1 = subplot(2,4,1,'Parent',p);
Creates new axes. Because it overlays the previously created axes, those are deleted.
plot(xData(idx,1),yData(idx,1))
Plots to the current axes (i.e. the one created by subplot). These axes don't have the "hold" property set, so subsequent plot commands will overwrite the data plotted here.
The solution, as suggested by Ander in a comment, is to set the "hold" property of the axes created by subplot. Replace:
cla; hold on; grid on, box on;
ax1 = subplot(2,4,1,'Parent',p);
with:
ax1 = subplot(2,4,1,'Parent',p);
hold on; grid on, box on;
(note that cla is not necessary, since you're drawing to a new, empty figure).
Is there a way to remove only the axis lines in the Matlab figure, without affecting ticks and tick labels.
I know that box toggles the upper and right axes lines and ticks and that works perfectly for me.
But my problem is that I want eliminate the bottom and left lines (only lines!) but keeping the ticks and tick labels.
Any tricks?
Yair Altman's Undocumented Matlab demonstrates a cleaner way to do this using the undocumented axes rulers:
plot(x,y);
ax1 = gca;
yruler = ax1.YRuler;
yruler.Axle.Visible = 'off';
xruler = ax1.XRuler;
xruler.Axle.Visible = 'off'; %// note you can do different formatting too such as xruler.Axle.LineWidth = 1.5;
A nice feature of this approach is that you can separately format the x and y axis lines.
Solution for Matlab versions prior to R2014b
You can introduce a new white bounding box and put it on top.
// example data
x = linspace(-4,4,100);
y = 16 - x.^2;
plot(x,y); hold on
ax1 = gca;
set(ax1,'box','off') %// here you can basically decide whether you like ticks on
%// top and on the right side or not
%// new white bounding box on top
ax2 = axes('Position', get(ax1, 'Position'),'Color','none');
set(ax2,'XTick',[],'YTick',[],'XColor','w','YColor','w','box','on','layer','top')
%// you can plot more afterwards and it doesn't effect the white box.
plot(ax1,x,-y); hold on
ylim(ax1,[-30,30])
Important is to deactivate the ticks of the second axes, to keep the ticks of the f rist one.
In Luis Mendo's solution, the plotted lines are fixed and stay at their initial position if you change the axes properties afterwards. That won't happen here, they get adjusted to the new limits. Use the correct handle for every command and there won't be much problems.
Dan's solution is easier, but does not apply for Matlab versions before R2014b.
There is another undocumented way (applicable to MATLAB R2014b and later versions) of removing the lines by changing the 'LineStyle' of rulers to 'none'.
Example:
figure;
plot(1:4,'o-'); %Plotting some data
pause(0.1); %Just to make sure that the plot is made before the next step
hAxes = gca; %Axis handle
%Changing 'LineStyle' to 'none'
hAxes.XRuler.Axle.LineStyle = 'none';
hAxes.YRuler.Axle.LineStyle = 'none';
%Default 'LineStyle': 'solid', Other possibilities: 'dashed', 'dotted', 'dashdot'
This is different from Dan's answer which uses the 'visible' property of rulers.
You could "erase" the axis lines by plotting a white line over them:
plot(1:4,1:4) %// example plot
box off %// remove outer border
hold on
a = axis; %// get axis size
plot([a(1) a(2)],[a(3) a(3)],'w'); %// plot white line over x axis
plot([a(1) a(1)],[a(3) a(4)],'w'); %// plot white line over y axis
Result:
As noted by #SardarUsama, in recent Matlab versions you may need to adjust the line width to cover the axes:
plot(1:4,1:4) %// example plot
box off %// remove outer border
hold on
a = axis; %// get axis size
plot([a(1) a(2)],[a(3) a(3)],'w', 'linewidth', 1.5); %// plot white line over x axis.
%// Set width manually
plot([a(1) a(1)],[a(3) a(4)],'w', 'linewidth', 1.5);
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 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 :)
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 :