Различные точки рассеяния цвета без использования Hold on (или всех)

Я хотел бы создать точечную диаграмму в MATLAB, используя три набора данных. X, Y и c. X и Y должны быть соответствующими осевыми графиками, но c содержит информацию (целочисленные значения) по каждой классификации точек рассеяния. Я хочу сделать каждый график классификации отдельным цветом. Эти целочисленные значения достаточно просты, чтобы их можно было преобразовать в соответствующие варианты цвета, так что проблем не возникнет. В настоящее время, выбрав цвет C, я использую,

    hold on
for k=1:K
    scatter(X(c==k,:),Y(c==k),[],C(k,:),'filled');
end

Моя мотивация для этого заключается в том, что я хочу создать UpdateFcn в DataCursorManager, чтобы отображать даты каждой точки с помощью курсора данных. Мне не удалось сделать это с несколькими диаграммами рассеяния, и я решил, что это самый простой способ решения проблемы.


person Little Bobby Tables    schedule 29.04.2015    source источник


Ответы (1)


Как сказано в комментарии, scatter может принимать 4-й аргумент, который будет представлять цвет. Третий аргумент (тот, который вы используете с c для каждой диаграммы рассеяния) управляет только размером.

Для вас способ вызова scatter должен быть таким: scatter(x,y, size, colour , 'filled')

Внимательно прочитайте документацию по scatter, чтобы лучше понять его использование.

Ниже приведен краткий пример того, как использовать его с 4 параметрами. Мне пришлось создать образцы данных, так как вы ничего не указали (я выбрал даты на оси x, и я предположил, что вам нужен одинаковый размер для всех групп... но отрегулируйте это в соответствии с вашими потребностями).

Обратите внимание, что объект разброса имеет свойство с именем CData. Это тот же размер, что и x, и он содержит цвет для каждой точки данных (хорошо, индекс цвета в палитре рисунка). Это то, что мы используем, чтобы узнать классификацию вашей точки в функции подсказки данных. Вы можете напрямую изменить этот вектор CData, если хотите изменить цвет в интерактивном режиме.

function h = scatter_datatip_demo

%// basic sample data
npts = 50 ;
nClass = 12 ; %// let's say we have 12 different class
x = round(now) + randi([-10 10],npts,1) ;
y = rand(size(x)) ;
s = ones(size(x))*40 ;
c = randi([1 nClass],size(x)); %// randomly assign a class for each point

%// Draw a single scatter plot (specifying the colour as the 4th input)
h.f = figure ;
h.p = scatter(x,y , s , c , 'filled') ; %// <== Note how scatter is called
colormap( jet(nClass) ) ;

%// add custom datatip function
set( datacursormode(h.f) , 'UpdateFcn',@customDatatipFunction );


function output_txt = customDatatipFunction(~,evt)
    pos = get(evt,'Position');

    hp = handle( get(evt,'Target') ) ;           %// get the handle of the scatter plot object
    ptClass = hp.CData( get(evt,'DataIndex') ) ; %// get the colour index of the current point

    output_txt = { ...
        'My custom datatip' , ...
        ['Date : ' , datestr(pos(1))  ] ...
        ['Class: ' , num2str(ptClass) ] ...
        ['Value: ' , num2str(pos(2),8)] ...
                };

demoimg

person Hoki    schedule 29.04.2015
comment
Вау, спасибо @Hoki. Это сработало отлично. Я пытался в течение нескольких часов добраться до этой точки. Хоть что-то объяснить? Почему вы используете ~ в customDatatipFunction(~,evt)? - person Little Bobby Tables; 29.04.2015
comment
@josh, оператор ~ вместо аргумента указывает компилятору, что вы не будете использовать этот аргумент (поэтому m-lint не будет жаловаться позже, что вы его не используете). В большинстве функций обратного вызова первым параметром обычно является дескриптор вызывающего объекта, часто полезный, но в случае datatip он всегда пуст, поэтому на самом деле нет необходимости присваивать его переменной. Итак, ~ просто говорит игнорировать это. Вы можете прочитать эту статью. для более подробной информации. - person Hoki; 29.04.2015
comment
@josh, на самом деле, эта статья является начальной (ссылка, которую я дал выше, является лишь продолжением). - person Hoki; 29.04.2015
comment
В порядке. Я попытался изменить его так, чтобы отметка даты не была переменной X, но мне не повезло с этим. Отчасти потому, что я не знаю, на что ссылается evt в функции @customDatatipFunction(~,evt). Информация о моей дате хранится в date. Спасибо - person Little Bobby Tables; 29.04.2015
comment
Правильно, так. Теперь я понял это до некоторой степени, установив ZData=datenum(date) (поскольку мой date был датой и временем) для моих соответствующих значений даты. Затем я использовал datestr(pos(3)) для отображения даты в поле курсора данных. - person Little Bobby Tables; 29.04.2015
comment
Заключительный пост: теперь я использую UserData вместо ZData, так что у меня есть UData=hp.UserData(get(evt,'DataIndex'));, а затем datestr(UData). Я предполагаю, что это более общая версия, поскольку ее можно использовать вместе с scatter3. - person Little Bobby Tables; 29.04.2015
comment
@джош. Отличная работа. userdata — один из способов сделать это, и он достаточно чистый. Если это вызывает у вас затруднения, посмотрите setappdata и getappdata (документация). evt относится к объекту eventdata, возвращенному datatip. Если вы поместите точку останова в режим отладки, вы увидите, что она содержит текущую позицию и индекс данных. - person Hoki; 29.04.2015