Hi I have a image in MATLAB
and I want the line to be smooth - look at the line from 0.4 to 0.8... it's horrible.
When using 'LineSmoothing','on' operator in plot I get this
I does a good job on lines but it smooths markers also and they are horrible!!
How can I get MATLAB to smooth only lines and not the markers??
Here is the code:
clear all;
close all;
bpp = [0.8 0.4 0.2 0.1 0.05];
bpp_j = [0.8 0.4 0.2 0.1];
AAE_JPEG = [1.65 2.91 6.20 10.96];
AAE_JPEG_2000 = [1.39 2.29 3.78 6.75 12.52];
AAE_EEDC = [2.08 2.67 3.80 5.94 9.31];
hold on;
plot(bpp_j, AAE_JPEG, 'k','LineWidth',1.5,'MarkerSize',9,'MarkerEdgeColor','k','LineSmoothing','on');
plot(bpp, AAE_JPEG_2000, 'k', 'LineWidth',1.5,'MarkerSize',6,'MarkerEdgeColor','k','LineSmoothing','on');
plot(bpp, AAE_EEDC, 'k', 'LineWidth',1.5,'MarkerSize',6,'MarkerEdgeColor','k','LineSmoothing','on');
plot(bpp_j, AAE_JPEG, 'x','LineWidth',1.5,'MarkerSize',8,'MarkerEdgeColor','k');
plot(bpp, AAE_JPEG_2000, 'o', 'LineWidth',1.5,'MarkerSize',6,'MarkerEdgeColor','k');
plot(bpp, AAE_EEDC, 'v', 'LineWidth',1.5,'MarkerSize',6,'MarkerEdgeColor','k');
LL = plot(rand(1,2),rand(1,2),'k-x','visible','off','LineWidth',1.5,'MarkerSize',8);
LK = plot(rand(1,2),rand(1,2),'k-o','visible','off','LineWidth',1.5,'MarkerSize',6);
LI = plot(rand(1,2),rand(1,2),'k-v','visible','off','LineWidth',1.5,'MarkerSize',6);
legend([LL,LK, LI],'JPEG','JPEG 2000','EEDC')
axis([0 0.9 0 14])
xlabel('bpp');
ylabel('AAE');
grid on;
and while I'm still here... how can I only display 0.05 0.1 0.2 0.4 and 0.8 on x-axis?
I'd just try using export_fig without even linesmoothing the lines...
I don't have a MATLAB here so I can't test but does it work if you plot the smoothed lines without markers
plot(bpp_j, AAE_JPEG, 'k','LineWidth',1.5,'LineSmoothing','on');
then another plot of the markers with no lines?
plot(bpp_j, AAE_JPEG, 'x','MarkerSize',8,'MarkerEdgeColor','k');
As for the x-axis ticks see matlab x axis label set as a vector
Related
In this figure, the marker in the legend is so big, how can I make it shorter.
I spend a lot of time searching for the solution online. But I did not find any solution that can fix this problem.
Thanks.
This is the code,
latency = [1 1.3 0.5;...
0.8 1.2 0.4;...
0.7 1.1 0.35;...
0.9 1.0 0.3;...
0.8 1.2 0.4;...
0.7 1.1 0.3];
h = bar(latency);
set(h(1), 'FaceColor',[33 36 61]./255)
set(h(2), 'FaceColor',[240 240 240]./255)
set(h(3), 'FaceColor',[250 128 114]./255)
set(h, 'LineWidth', 1);
set(gca,'Linewidth',1,'Fontname', 'arial');
set(gca, 'XLim', [0, size(latency,1)+1])
set(gca, 'YLim', [0 max(max(latency))*1.1]);
xlabel('(a) Latency','FontSize',14)
ylabel('Latency (us)','FontSize',14)
legend({'AAAAAAAA', 'BBBBBBBB', 'CCCCCCCC'}, 'Orientation', 'horizontal','FontSize',11)
box on;
Update:
According to the answer, I add two lines of codes:
[lgd,icons,plots,txt] = legend({'AAAAAAAA', 'BBBBBBBB', 'CCCCCCCC'});
icons(4).Children.XData = icons(4).Children.XData/2;
Now I get this legend.
But there is a blank space before text.
There is an undocumented propertie ItemTokenSize to do that:
% Fixe the new size of each box:
box_size = [10 10 10]
% Get the handle
hdl = legend({'AAA', 'BBB', 'CCC'})
% Set the new size
hdl.ItemTokenSize = box_size;
% Then recenter the legend
% ...
Undocumented means that this option could be deleted, without notice, in a future release.
I want to visualize the peaks of a function, and I want to have markers for it appear above the line they are associated with.
I fabricated a minimum example where I already have the peaks, the question is just how to visualize the markers correctly:
y = [0.1 0.3 10.0 1.0 0.5 0.1 24.0 0.6 0.1 0.2]
x = (1:length(y))
plot(x,y);
hold on;
peaks = [3 7];
plot(x(peaks), y(peaks), 'v', 'MarkerSize', 24);
print('-dpng', 'example.png', '-S640,480');
So, as a result, the markers appear centered on the line like this:
The result that I want could be achieved by carefully tuning a parameter OFFSET like this:
plot(x(peaks), y(peaks)+OFFSET, 'v', 'MarkerSize', 24);
As shown in the following figure, for this exact example OFFSET=2.56 works for the exported png, but with the interactive plot and exporting vector graphics, it's wrong again.
Can anyone recommend a way to get this result without having to manually doing trial/error?
Currently I am using Octave with gnuplot to export to latex+tikz, and it would be good if the solution would work there.
In my actual (more complicated) use case I am plotting multiple lines after each other into the same figure, and the y limits change, so the offsets can not just be calculated easily, as the markersize doesn't change with the y limits.
Edit: Additionally I am using a semilogx plot, so drawing lines inside the diagram in the x/y-Axis scales would look distorted.
One way to do this is with annotations, but there are some drawbacks (see below).
Annotations enable you to place various graphic objects into your figure. One very annoying thing about them is that they work in so-called normalized coordinates,
which span the whole figure window (not just the plot area) and go from [0,0] to [1,1], forcing you to convert to these coordinates first. I wrote a simple function to do this, provided your plot scale is linear (if you want logarithmic, you will have to modify this function):
## Convert from data coordinates to normalized figure coordinates.
function [xf yf] = figcoords(xa, ya)
axp = get(gca, "position");
lf = axp(1);
bf = axp(2);
rf = lf + axp(3);
tf = bf + axp(4);
xl = xlim();
yl = ylim();
la = xl(1);
ra = xl(2);
ba = yl(1);
ta = yl(2);
xf = lf + (xa-la).*(rf-lf)./(ra-la);
yf = bf + (ya-ba).*(tf-bf)./(ta-ba);
endfunction
With this out of your way, you can proceed to annotating the plot using the annotation function:
y = [0.1 0.3 10.0 1.0 0.5 0.1 24.0 0.6 0.1 0.2];
x = (1:length(y));
peaks = [3 7];
## Plot the data as you would normally
plot(x,y);
## Plot peak markers (no `hold on` needed)
[xp yp] = figcoords(peaks, y(peaks)); # Transform to figure coordinates
for coords = [xp; yp]
xpi = coords(1);
ypi = coords(2);
annotation("arrow", [xpi xpi], [ypi+eps ypi]);
endfor
Plot with annotated peaks
Here, we actually draw little arrows pointing from top onto the peaks.
As their height is very small, we only see the arrowheads.
The arguments to the annotation function are the x and y coordinates
of the endpoints of the arrow. Note that we added a small number (eps)
to the y-value of the starting point to make the arrow point downward.
If you want, you can tweak the appearance of the markers to make them more visually appealing:
y = [0.1 0.3 10.0 1.0 0.5 0.1 24.0 0.6 0.1 0.2];
x = (1:length(y));
peaks = [3 7];
coloridx = get(gca, "ColorOrderIndex")
peakcolor = get(gca, "ColorOrder")(coloridx,:); # Save current plot colour
plot(x,y);
## Plot peak markers
[xp yp] = figcoords(peaks, y(peaks));
for coords = [xp; yp]
xpi = coords(1);
ypi = coords(2);
annotation("arrow", [xpi xpi], [ypi+eps ypi], "headstyle", "plain",...
"color", peakcolor);
endfor
Plot with annotated peaks in the same color
Drawbacks
While this approach works fine regardless of the size of the markers or your plot, there are some drawbacks:
First, the annotations are fixed relative to the figure window, not the plot.
This is fine when you display the plot for the first time, but once you zoom
or pan, the alignment is lost: The markes stay in place while the plot moves.
If you don't need an interactive plot (eg, you just want to export it to image),
just be sure to set the plot limits before adding the annotations and you should
be fine.
Second, this method is very slow compared to plotting the points using the
plot function. On my computer, for example, when drawing a simple example with
seven annotated peaks, it takes about a second before the markers appear.
Plotting a signal with thousands of peaks is near impossible.
Concerning the Matlab part, you could draw the peak markers yourself. Somewhere along these lines (extending your example):
y = [0.1 0.3 10.0 1.0 0.5 0.1 24.0 0.6 0.1 0.2]
x = (1:length(y))
figure, plot(x,y);
leglengthx=0.2;
leglengthy=0.5;
hold on;
peaks = [3 7];
peaks_max=[10 24];
for ii=1:2
line([peaks(ii) peaks(ii)+leglengthx],[peaks_max(ii) peaks_max(ii)+leglengthy]);
line([peaks(ii) peaks(ii)-leglengthx],[peaks_max(ii) peaks_max(ii)+leglengthy]);
line([peaks(ii)-leglengthx peaks(ii)+leglengthx],[peaks_max(ii)+leglengthy peaks_max(ii)+leglengthy]);
end
plot(x(peaks), y(peaks), 'v', 'MarkerSize', 24);
I have added the maxima of the peaks, which should not be an issue to automatically extract and two variables that control the triangle size of the marker. And then its just drawing three lines for every peak.
I don't know how this will translate to Octave.
What about drawing the little triangles?
y = [0.1 0.3 10.0 1.0 0.5 0.1 24.0 0.6 0.1 0.2];
x = (1:length(y));
peaks = [3 7];
plot(x,y);
hold on; line([peaks(1) peaks(1)+0.2], [y(x==peaks(1)) y(x==peaks(1))+1], 'color','b')
hold on; line([peaks(1) peaks(1)-0.2], [y(x==peaks(1)) y(x==peaks(1))+1], 'color','b')
hold on; line([peaks(1)+0.2 peaks(1)-0.2], [y(x==peaks(1))+1 y(x==peaks(1))+1], 'color','b')
hold on; line([peaks(2) peaks(2)+0.2], [y(x==peaks(2)) y(x==peaks(2))+1], 'color','b')
hold on; line([peaks(2) peaks(2)-0.2], [y(x==peaks(2)) y(x==peaks(2))+1], 'color','b')
hold on; line([peaks(2)+0.2 peaks(2)-0.2], [y(x==peaks(2))+1 y(x==peaks(2))+1], 'color','b')
There can be a problem if the y-values of the peaks exists in other locations on the vector. If so, you can specify first or other matching specs for the find function.
I have some 2D points and I want to plot them in MATLAB such that every point has a different color and specifier. I have used plot function but it creates line whatever you give. I want to draw these points as discrete points only. How can I do that? Here is what I am trying to achieve in the simplest form (I used TikZ below):
UPDATE:
Thank you for your comments and answers, I have the following code right now:
x = [ 0.56, 0.4526, -0.4324, 0.2749, -0.2993, 0.3404, 0.1959, 0.3363, -0.1706];
y = [0.1999, 0.3939, 0.1999, 0.4414, 0.2000, 0.3931, 0.1999, 0.3966, 0.4056];
figure
plot(x(1),y(1),'rx')
hold on
plot(x(2),y(2),'*','Color','[0 0.9 0]')
hold on
plot(x(3),y(3),'*','Color','[0 0.5 0]')
hold on
plot(x(4),y(4),'o','Color','[0.47 0.52 0.8]','MarkerFaceColor','[0.47 0.52 0.8]')
hold on
plot(x(5),y(5),'o','Color','[0.05 0.28 0.63]','MarkerFaceColor','[0.05 0.28 0.63]')
hold on
plot(x(6),y(6),'s','Color','[1 0.71 0.30]','MarkerFaceColor','[1 0.71 0.30]')
hold on
plot(x(7),y(7),'s','Color','[0.9 0.32 0]','MarkerFaceColor','[0.9 0.32 0]')
%plot(x(7),y(7),'s','Color','[1 0 0.5]','MarkerFaceColor','[1 0 0.5]')
hold on
plot(x(8),y(8),'d','Color','[0.67 0.28 0.73]','MarkerFaceColor','[0.73 0.40 0.78]')
%plot(x(8),y(8),'d','Color','[0.67 0.28 0.73]','MarkerFaceColor','[0.67 0.28 0.73]')
hold on
plot(x(9),y(9),'d','Color','[0.29 0.08 0.55]','MarkerFaceColor','[0.29 0.08 0.55]')
xlabel('X')
ylabel('Y')
h = legend('(^1X,^1Y)','(^2X_1,^2Y_1)','(^2X_2,^2Y_2)','(^3X_1,^3Y_1)','(^3X_2,^3Y_2)','(^4X_1,^4Y_1)','(^4X_2,^4Y_2)','(^5X_1,^5Y_1)','(^5X_2,^5Y_2)');
set(h,'Location','best')
grid
I can now draw the points as dots with different colors and specifiers although this way may not be the best way.
You can simply specify the LineSpec option
http://fr.mathworks.com/help/matlab/ref/plot.html#inputarg_LineSpec
To obtain your example:
plot(xdata, ydata, '.')
How can I plot only a color bar, e.g. jet from -1 to 1, in Matlab? I need to save it as an image.
Running colorbar also plots an empty axis next to the color bar.
what about this:
colorbar
axis off
EDIT :
If you want to fully control the width and position of the colorbar then you can do something like:
fig1=figure;
left=100; bottom=100 ; width=20 ; height=500;
pos=[left bottom width height];
axis off
colorbar([0.1 0.1 0.7 0.8]);
set(fig1,'OuterPosition',pos)
As MATLAB can only print (= save as an image) figures and colorbar doesn't return a figure handle, one way is to install http://www.mathworks.com/matlabcentral/fileexchange/23629-exportfig, then use:
colormap('jet');
cbar_handle = colorbar;
export_fig(cbar_handle, 'colorbar.png');
colorbar.png:
Inspired by bla, here is an answer with more adjusting possibilities. (Rep<50 means no comments possible. sry!)
fig1=figure;
axis off
colormap(gray(100));
caxis([-1 1]);
h = colorbar([0.1 0.1 0.8 0.7],...
'location','Southoutside',...
'XTick',[-1 -0.5 0 0.5 1]);
set(h,'OuterPosition',[0.1 0.1 0.8 0.8]);
Let us say we have a 1-by-2 subplot and we plot some graphics inside as follows:
subplot(1,2,1)
surf(peaks(20))
subplot(1,2,2)
surf(peaks(20))
And then we want to put a colorbar:
colorbar
I don't want the right figure squezzed as in the result. How can we put the colorbar out of the rightmost figure in a row of subplots and keep the sizes of them unchanged?
Note: Actually, I need it for plotting images where the colorbar is common and I want to put it on the right. I used this toy example for simplicity.
You could just extract the position of the first plot and use on the second. MATLAB automatically moves the colorbar to the right when rescaling.
f1=figure(1);clf;
s1=subplot(1,2,1);
surf(peaks(20));
s2=subplot(1,2,2);
surf(peaks(20));
hb = colorbar('location','eastoutside');
%% # Solution:
s1Pos = get(s1,'position');
s2Pos = get(s2,'position');
s2Pos(3:4) = [s1Pos(3:4)];
set(s2,'position',s2Pos);
%% # Alternative method. Brute force placement
set(s1,'Units','normalized', 'position', [0.1 0.2 0.3 0.6]);
set(s2,'Units','normalized', 'position', [0.5 0.2 0.3 0.6]);
set(hb,'Units','normalized', 'position', [0.9 0.2 0.05 0.6]);
This is just what I was looking for. After implementing Vidar's automatic solution I came up with a simplification. Get the position of the far right axes BEFORE adding the colorbar, and then just reset the squeezed position to the original:
f1=figure(1);clf;
s1=subplot(1,2,1);
surf(peaks(20));
s2=subplot(1,2,2);
surf(peaks(20));
s2Pos = get(s2,'position');
hb = colorbar('location','eastoutside');
set(s2,'position',s2Pos);