Круги с Альфа-значениями в MATLAB

Я создаю диаграмму рассеяния некоторых данных, как и вы, и у меня есть несколько повторяющихся точек данных, которые я хотел бы построить как круги с некоторым Альфа-значением, так что нагромождение дополнительных точек в том же месте очевидно.

насколько я могу сказать вы не можете установить Альфа свойства маленьких кругов, которые вы создаете с помощью plot(x, y, 'o'), поэтому я прибегнул к рисованию тысяч маленьких кругов с помощью 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

как вы можете видеть, это не оптимальный, как мне нужно знать, и установить размер участка (xlim и ylim), прежде чем я построю его так, чтобы круги в конечном итоге были круговыми. Если я изменю сюжет, они превратятся в овалы. Я также заканчиваю с миллионами объектов, что является болью при создании легенд.

есть ли более простой способ?

5 ответов


нашел patchline функция на обмене Matlab, которая может принимать любые patch аргументы, в том числе 'FaceAlpha':

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


Я не нашел способа иметь маркер линии с Альфой в MATLAB.

Если вы посмотрите на свойства линии (функция низкого уровня (mid) позади графика), вы увидите, что вы можете определить маркеры, а их единственными свойствами являются их цвет (MarkerEdgeColor или MarkerFaceColor), который не принимает Альфа (нет MarkerFaceAlpha свойства).

Итак,как вы это делаете с патчами, кажется, путь.

единственное, что я могу предложить, чтобы избежать миллиардами объекты должны быть сгруппированы в hggroup, что заставит их появиться как один объект в легенде.


Я попытался сделать общую функцию, используя patch. Он медленный и немного багги, но он работает нормально для простых случаев. MATLAB нужна настоящая Альфа-линия.

x и y - Это точки На участке, w ширина линии col цвета и a Альфа-значение.

пример:

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

у меня такая же проблема, и моя диаграмма рассеяния имеет 100 000 точек. Идея ответа №2 отличная, но для меня было непрактично открывать свой сюжет в Illustrator потому что у меня слишком много очков. Поэтому я адаптировал ответ #2 в пакетном режиме:

печать рисунка в pdf-файл в matlab:

print -dpdf foo.pdf

преобразование pdf-файла в svg с помощью pdf2svg из пакета debian pdf2svg:

pdf2svg foo.pdf foo.svg

сделать все синие объекты прозрачные:

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

преобразовать foo2.svg в pdf с помощью rsvg-конвертировать из пакета debian librsvg2-bin:

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

насколько я могу судить, нет способа напрямую установить Альфа для маркеров в MATLAB. Методы патча не работают хорошо, когда Альфа установлена ниже 0,03 или когда есть гораздо больше, чем 10 000 маркеров.

обходной путь для создания графики качества публикации, когда у вас есть плотное облако маркеров, чтобы дать маркерам уникальный цвет. Затем выведите цифру в EPS. Тогда откройте в иллюстратор выберите все объекты этого цвета и установить прозрачность и цвет объектов в Illustrator. Это не одноэтапное решение, на которое можно было бы надеяться, но оно дает намного, намного лучшие результаты, чем использование внутренних функций MATLAB, и быстро, если у вас есть Illustrator или эквивалентный пакет векторной графики.