2011-05-05 37 views
6

Tôi đang tạo một biểu đồ phân tán của một số dữ liệu, như bạn làm, và tôi có một số điểm dữ liệu lặp lại mà tôi muốn vẽ thành các vòng tròn với một số giá trị alpha để chồng chất trên các điểm phụ tại cùng một vị trí là hiển nhiên.Vòng tròn lô với giá trị alpha trong MATLAB

Theo như tôi có thể nói bạn không thể thiết lập các thuộc tính alpha của các vòng tròn nhỏ mà bạn tạo ra với plot(x, y, 'o'), vì vậy tôi đã viện đến vẽ hàng ngàn vòng tròn nhỏ bằng patch() bản thân mình:

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 

Như bạn có thể thấy, đây không phải là tối ưu vì tôi cần biết và đặt kích thước của ô (xlimylim) trước khi vẽ đồ thị sao cho vòng tròn kết thúc bằng hình tròn. Nếu tôi định hình lại cốt truyện thì chúng sẽ trở thành hình bầu dục. Tôi cũng kết thúc với hàng triệu đồ vật, đó là một nỗi đau khi thực hiện truyền thuyết.

Có cách nào dễ dàng hơn không?

+2

bạn có thể thêm một cuộc gọi ví dụ để chức năng của bạn? Sẽ dễ dàng hơn nếu không phải đọc chi tiết để tìm ra cú pháp ... – abcd

+0

Vâng, ý tưởng hay. – Alex

+0

Với bản phát hành MATLAB mới có vẻ như có thể nhưng nó vẫn không có giấy tờ. Xem [tại đây] (http://undocumentedmatlab.com/blog/plot-markers-transparency-and-color-gradient) – WYSIWYG

Trả lời

4

Tôi không tìm thấy cách nào để có điểm đánh dấu đường bằng alpha trong MATLAB.

Nếu bạn nhìn vào các thuộc tính đường thẳng (hàm trung bình thấp phía sau ô), bạn sẽ thấy rằng bạn có thể xác định điểm đánh dấu và thuộc tính duy nhất của chúng là màu của chúng (MarkerEdgeColor hoặc MarkerFaceColor). (không có số MarkerFaceAlpha).

Vì vậy, cách bạn thực hiện việc đó bằng các bản vá có vẻ là cách để thực hiện.

Điều duy nhất tôi có thể đề xuất để tránh có hàng tỷ đối tượng là nhóm chúng trong một hggroup, điều này sẽ làm cho chúng xuất hiện dưới dạng một đối tượng duy nhất trong chú giải.

3

Tôi đã cố gắng thực hiện chức năng chung bằng cách sử dụng patch. Đó là chậm và một chút lỗi, nhưng nó hoạt động OK cho các trường hợp đơn giản. Tuy nhiên, MATLAB cần alpha thực.

xy là các điểm cần vẽ, w chiều rộng của đường kẻ, col màu và a giá trị alpha.

Ví dụ:

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

Khi đến nay tôi có thể nói, không có cách nào để trực tiếp đặt alpha cho năng đánh dấu trong MATLAB. Phương pháp vá không hoạt động tốt khi alpha được đặt dưới mức khoảng 0,03 hoặc khi có hơn 10.000 điểm đánh dấu.

Cách khắc phục để tạo đồ họa chất lượng xuất bản khi bạn có một đám mây dày đặc các điểm đánh dấu là cung cấp cho các điểm đánh dấu một màu duy nhất. Sau đó in hình thành EPS. Sau đó, mở trong Illustrator, chọn tất cả các đối tượng có màu đó và đặt độ trong suốt và màu sắc của các đối tượng trong Illustrator. Nó không phải là giải pháp một bước mà hy vọng, nhưng nó cho kết quả tốt hơn nhiều so với sử dụng các hàm MATLAB bên trong và nhanh chóng, miễn là bạn có Illustrator hoặc một gói đồ hoạ vector tương đương.

3

Tôi có cùng một vấn đề và âm mưu phân tán của tôi có 100.000 điểm. Ý tưởng câu trả lời # 2 rất tuyệt, nhưng tôi không thể mở cốt truyện của mình trong Illustrator vì tôi có quá nhiều điểm.Vì vậy, tôi thích câu trả lời # 2 vào một quá trình hàng loạt:

in hình vào một tập tin pdf trong matlab:

print -dpdf foo.pdf 

chuyển đổi file pdf sang SVG sử dụng pdf2svg từ gói debian pdf2svg:

pdf2svg foo.pdf foo.svg 

làm cho tất cả đối tượng màu xanh trong suốt:

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

convert foo2.svg để pdf sử dụng rsvg-convert từ debian gói librsvg2-bin:

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