Круги с Альфа-значениями в 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 или эквивалентный пакет векторной графики.