在MATLAB中用alpha值绘制圆圈

时间:2011-05-05 06:28:42

标签: matlab

我正在创建一些数据的散点图,就像你一样,我有一些重复的数据点,我想将它们绘制成具有一些alpha值的圆圈,以便在相同的点上堆积额外的点位置很明显。

据我所知,你无法设置用plot(x, y, 'o')生成的小圆圈的alpha属性,所以我自己使用patch()绘制了数千个小圆圈:

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

正如您所看到的,这不是最佳的,因为在绘制之前我需要知道并设置绘图的大小(xlimylim),以便圆圈最终成为圆形。如果我重新塑造情节,那么它们最终会成为椭圆形。我最终还有数以百万计的物品,这在传说中是一种痛苦。

有更简单的方法吗?

5 个答案:

答案 0 :(得分:4)

我发现无法在MATLAB中使用包含alpha的行标记。

如果你看一下线属性(图中背后的(中)低级函数),你会看到你可以定义标记,它们的唯一属性是它们的颜色(MarkerEdgeColorMarkerFaceColor) ,不带任何alpha(没有MarkerFaceAlpha属性)。

所以如何使用补丁来实现它似乎是要走的路。

我唯一可以避免拥有数以万计的对象的建议是将它们分组在hggroup中,这会使它们在图例中显示为单个对象。

答案 1 :(得分:3)

我尝试使用patch执行常规功能。它很慢而且有点儿麻烦,但它适用于简单的情况。 MATLAB需要一个实线alpha。

xy是要绘制的点,w线宽,col颜色和a alpha值。

示例:

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

答案 2 :(得分:3)

我有同样的问题,我的散点图有100,000点。 回答#2的想法很棒,但在Illustrator中打开我的情节对我来说是不切实际的 因为我得分太多了所以我将答案#2改编成批处理过程:

将图形打印到matlab中的pdf文件:

print -dpdf foo.pdf

使用debian package pdf2svg中的pdf2svg将pdf文件转换为svg:

pdf2svg foo.pdf foo.svg

使所有蓝色物体透明:

sed '/rgb(0%,0%,100%)/s/fill-opacity:1/fill-opacity:.2' < foo.svg > foo2.svg

使用debian包中的rsvg-convert将foo2.svg转换为pdf  librsvg2斌:

rsvg-convert -f pdf -o foo2.pdf foo2.svg

答案 3 :(得分:2)

据我所知,没有办法直接为MATLAB中的标记设置alpha。当alpha设置低于约0.03或者远远超过10,000个标记时,补丁方法无法正常工作。

当您拥有密集的标记云时,生成发布质量图形的解决方法是为标记提供独特的颜色。然后将图形打印到EPS。然后在Illustrator中打开,选择该颜色的所有对象,并在Illustrator中设置对象的透明度和颜色。它不是人们所希望的一步式解决方案,但它确实提供了比使用内部MATLAB函数更好,更好看的结果,并且快速,只要你有Illustrator或等效的矢量图形包。

答案 4 :(得分:2)

在Matlab Exchange上找到patchline函数,该函数可以包含patch'FaceAlpha'个参数:

http://www.mathworks.com/matlabcentral/fileexchange/36953-patchline/content/patchline.m