I'm creating a scatter plot of some data, as you do, and I have a number of repeated data points which I'd like to plot as circles with some alpha value so that piling on of extra points at the same location is obvious.
As far as I can tell you cannot set the alpha properties of the little circles that you generate with plot(x, y, 'o')
, so I've resorted to drawing thousands of little circles using patch()
myself:
x = repmat([1:10], [1 10]);
y = round(10*rand(100, 1))/10;
xlim([0 11])
ylim([0 1])
p = ag_plot_little_circles(x', y, 10, [1 0 .4], 0.2);
function p = ag_plot_little_circles(x, y, circle, col, alpha)
%AG_PLOT_LITTLE_CIRCLES Plot circular circles of relative size circle
% Returns handles to all patches plotted
% aspect is width / height
fPos = get(gcf, 'Position');
% need width, height in data values
xl = xlim();
yl = ylim();
w = circle*(xl(2)-xl(1))/fPos(3);
h = circle*(yl(2)-yl(1))/fPos(4);
theta = 0:pi/5:2*pi;
mx = w*sin(theta);
my = h*cos(theta);
num = 0;
for k = 1:max(size(x))
for f = 1:size(y,2)
num = num+1;
p(num) = patch(x(k)+mx, y(k,f)+my, col, 'FaceColor', col, 'FaceAlpha', alpha, 'EdgeColor', 'none');
end
end
end
As you can see, this is not optimal as I need to know and set the size of the plot (xlim
and ylim
) before I plot it so that the circles end up being circular. If I reshape the plot then they end up as ovals. I also end up with millions of objects, which is a pain when making legends.
Is there an easier way?
Include the Greek letters α and μ in the text using the TeX markups \alpha and \mu , respectively. Add text at the data point where t = 300 . Use the TeX markup \bullet to add a marker to the specified point and use \leftarrow to include an arrow pointing to the left.
Set the properties to a scalar value in the range [0,1] . A value of 0 means completely transparent, a value of 1 means completely opaque, and values between 0 and 1 are semitransparent. Patch, surface, scatter, and image objects support using alpha data to vary the transparency across the object.
alpha sets one of three transparency properties, depending on what arguments you specify with the call to this function. FaceAlpha. alpha(face_alpha) sets the FaceAlpha property of all image, patch, and surface objects in the current axes.
I have found no way to have a line marker with alpha in MATLAB.
If you look at line properties (the (mid) low level function behind plot), you will see that you can define markers, and their sole properties are their color (MarkerEdgeColor
or MarkerFaceColor
), which does not take any alpha (there is no MarkerFaceAlpha
property).
So how you do it with patches seems the way to go.
The only thing I can propose to avoid having zillions of objects would be to group them in a hggroup, which will make them appear as a single object in the legend.
I tried to do a general function using patch
. It's slow and a bit buggy, but it works OK for simple cases. MATLAB needs a real-line alpha though.
x
and y
are points to plot, w
the width of the line, col
the color and a
the alpha value.
Example:
x = linspace(-2,2,100);
plotWithAlpha(x,sin(4*x),0.04,'r',0.2)
function [] = plotWithAlpha(x,y,w,col,a)
%function [] = plotWithAlpha(x,y,w,col,a)
if(size(x,1) ~= 1)
x = x.';
end
if(size(x,1) ~= 1)
y = y.';
end
sz = length(x);
% Calculate derrivatives of the curve
X = csaps(1:sz(1),x,1);
Y = csaps(1:sz(1),y,1);
mx = fnval(fnder(X,1),1:sz(1)).';
my = fnval(fnder(Y,1),1:sz(1)).';
T = [mx my]; %tangent
% Normalize tangents
T = bsxfun(@rdivide,T,sqrt(sum(T.^2,2)));
N = zeros(size(T));
N(:,2) = 1;
N(:,1) = -T(:,2)./T(:,1);
N = bsxfun(@rdivide,N,sqrt(sum(N.^2,2)));
N = N.';
hold on
for i = 2:length(x)
X = [x(i-1)+w*N(1,i-1) x(i)+w*N(1,i) x(i-1)-w*N(1,i-1) x(i)-w*N(1,i)];
Y = [y(i-1)+w*N(2,i-1) y(i)+w*N(2,i) y(i-1)-w*N(2,i-1) y(i)-w*N(2,i)];
% Order the points
D = pdist([X' Y']);
D = squareform(D); D(D==0) = Inf;
inds = 1;
D(:,1) = Inf;
[val ind] = min(D(1,:));
inds(2) = ind;
D(:,ind) = Inf;
[val ind] = min(D(ind,:));
inds(3) = ind;
D(:,ind) = Inf;
inds(4) = setxor(inds,1:4);
X = X(inds);
Y = Y(inds);
patch(X,Y,col,'edgeColor','none','FaceAlpha',a)
end
hold off
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With