2011-05-05 25 views
6

Estoy creando un gráfico de dispersión de algunos datos, como usted, y tengo una serie de puntos de datos repetidos que me gustaría trazar como círculos con algún valor alfa para que se acumulen de puntos extra en el mismo lugar es obvio.Trazar círculos con valores alfa en MATLAB

Por lo que yo puedo decir que no se puede establecer las propiedades alfa de los pequeños círculos que se generan con plot(x, y, 'o'), así que he recurrido a la elaboración de miles de pequeños círculos usando patch() a mí mismo:

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 

Como Puede ver, esto no es óptimo, ya que necesito saber y establecer el tamaño de la trama (xlim y ylim) antes de trazarlo para que los círculos terminen siendo circulares. Si vuelvo a dar forma a la trama, terminan como óvalos. También termino con millones de objetos, lo cual es un dolor al hacer leyendas.

¿Hay alguna manera más fácil?

+2

se puede añadir una llamada de ejemplo para su función? Sería más fácil no tener que leer en detalle para descubrir la sintaxis ... – abcd

+0

Sí, buena idea. – Alex

+0

Con el nuevo lanzamiento de matlab parece posible, pero aún no está documentado. Ver [aquí] (http://undocumentedmatlab.com/blog/plot-markers-transparency-and-color-gradient) – WYSIWYG

Respuesta

4

No he encontrado forma de tener un marcador de línea con alfa en MATLAB.

Si mira las propiedades de línea (la función de nivel bajo (medio) detrás de la gráfica), verá que puede definir marcadores, y sus únicas propiedades son su color (MarkerEdgeColor o MarkerFaceColor), que no toma ningún alfa (no hay propiedad MarkerFaceAlpha).

Entonces, ¿cómo lo haces con parches parece el camino a seguir.

Lo único que puedo proponer para evitar tener billones de objetos sería agruparlos en un hggroup, que los hará aparecer como un solo objeto en la leyenda.

3

He intentado hacer una función general usando patch. Es lento y con un poco de errores, pero funciona bien para casos simples. MATLAB necesita una línea real alfa.

x y y son puntos de trama, w la anchura de la línea, col el color y a el valor alfa.

Ejemplo:

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

Por lo que puedo decir, no hay manera de establecer directamente alfa para marcadores en MATLAB. Los métodos de parche no funcionan bien cuando el alfa está configurado por debajo de 0.03 o cuando hay más de 10.000 marcadores.

La solución para generar gráficos de calidad de publicación cuando se tiene una nube de marcadores densa es darles a los marcadores un color único. A continuación, imprima la figura en EPS. A continuación, abra en Illustrator, seleccione todos los objetos de ese color y establezca la transparencia y el color de los objetos en Illustrator. No es la solución de un paso que uno esperaría, pero da resultados mucho mejores y mucho mejores que el uso de funciones internas de MATLAB, y es rápida, siempre que tenga Illustrator o un paquete equivalente de gráficos vectoriales.

3

Tengo el mismo problema, y ​​mi diagrama de dispersión tiene 100.000 puntos. La idea de la respuesta n. ° 2 es excelente, pero no fue práctico para mí abrir mi trama en Illustrator porque tenía demasiados puntos.Así que me he adaptado respuesta # 2 en un proceso por lotes:

impresión de la figura en un archivo PDF en Matlab:

print -dpdf foo.pdf 

convertir el archivo pdf a SVG usando PDF2SVG de PDF2SVG paquete debian:

pdf2svg foo.pdf foo.svg 

crea todos los objetos de color azul transparente: foo2.svg

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

convertir a PDF usando rsvg-convert del debian paquete librsvg2-bin:

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