# 【Matlab】多维数据可视化方法之雷达图和气泡图

1. 雷达图

2. 多维数据可视化之气泡图

2.1 加载数据

2.2 3D气泡图

2.3 可点击图例

2.4 七维数据的3D可视化效果图

2.5 五维数据的2D可视化效果图

# 1. 雷达图

%% Example Script %%%
% Clear workspace
close all;
clearvars;
clc;

% Point properties
num_of_points = 6;
row_of_points = 4;

% Random data
P = rand(row_of_points, num_of_points);

% Scale points by a factor
P(:, 2) = P(:, 2) * 2;
P(:, 3) = P(:, 3) * 3;
P(:, 4) = P(:, 4) * 4;
P(:, 5) = P(:, 5) * 5;

% Make random values negative
P(1:3, 3) = P(1:3, 3) * -1;
P(:, 5) = P(:, 5) * -1;

% Create generic labels
P_labels = cell(num_of_points, 1);

for ii = 1:num_of_points
P_labels{ii} = sprintf('Label %i', ii);
end

% Figure properties
figure('units', 'normalized', 'outerposition', [0 0.05 1 0.95]);

% Axes properties
axes_interval = 2;
axes_precision = 1;

% Spider plot
spider_plot(P, P_labels, axes_interval, axes_precision,...
'Marker', 'o',...
'LineStyle', '-',...
'LineWidth', 2,...
'MarkerSize', 5);

% Title properties
title('Sample Spider Plot',...
'Fontweight', 'bold',...
'FontSize', 12);

% Legend properties
legend('show', 'Location', 'southoutside');

function spider_plot(P, P_labels, axes_interval, axes_precision, varargin)
% Create a spider web or radar plot with an axes specified for each column
%
% spider_plot(P, P_labels, axes_interval, axes_precision) creates a spider
% web plot using the points specified in the array P. The column of P
% contains the data points and the rows of P contain the multiple sets of
% data points. Each point must be accompanied by a label specified in the
% cell P_labels. The number of intervals that separate the axes is
% specified by axes_interval. The number of decimal precision points is
% specified by axes_precision.
%
% P - [vector | matrix]
% P_labels - [cell of string]
% axes_interval - [integer]
% axes_precision - [integer]
%
% spider_plot(P, P_labels, axes_interval, axes_precision, line_spec) works
% the same as the function above. Additional line properties can be added
% in the same format as the default "plot" function in MATLAB.
%
% line_spec - [character vector]
%
% %%%%%%%%%%%%%%%%%%% Example of a Generic Spider Plot %%%%%%%%%%%%%%%%%%%
% % Clear workspace
% close all;
% clearvars;
% clc;
%
% % Point properties
% num_of_points = 6;
% row_of_points = 4;
%
% % Random data
% P = rand(row_of_points, num_of_points);
%
% % Scale points by a factor
% P(:, 2) = P(:, 2) * 2;
% P(:, 3) = P(:, 3) * 3;
% P(:, 4) = P(:, 4) * 4;
% P(:, 5) = P(:, 5) * 5;
%
% % Make random values negative
% P(1:3, 3) = P(1:3, 3) * -1;
% P(:, 5) = P(:, 5) * -1;
%
% % Create generic labels
% P_labels = cell(num_of_points, 1);
%
% for ii = 1:num_of_points
%     P_labels{ii} = sprintf('Label %i', ii);
% end
%
% % Figure properties
% figure('units', 'normalized', 'outerposition', [0 0.05 1 0.95]);
%
% % Axes properties
% axes_interval = 2;
% axes_precision = 1;
%
% % Spider plot
% spider_plot(P, P_labels, axes_interval, axes_precision,...
%     'Marker', 'o',...
%     'LineStyle', '-',...
%     'LineWidth', 2,...
%     'MarkerSize', 5);
%
% % Title properties
% title('Sample Spider Plot',...
%     'Fontweight', 'bold',...
%     'FontSize', 12);
%
% % Legend properties
% legend('show', 'Location', 'southoutside');
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%%% Point Properties %%%
% Number of points
[row_of_points, num_of_points] = size(P);

%%% Error Check %%%
% Check if axes properties are an integer
if floor(axes_interval) ~= axes_interval || floor(axes_precision) ~= axes_precision
error('Error: Please enter in an integer for the axes properties.');
end

% Check if axes properties are positive
if axes_interval < 1 || axes_precision < 1
error('Error: Please enter value greater than one for the axes properties.');
end

% Check if the labels are the same number as the number of points
if length(P_labels) ~= num_of_points
error('Error: Please make sure the number of labels is the same as the number of points.');
end

% Pre-allocation
max_values = zeros(1, num_of_points);
min_values = zeros(1, num_of_points);
axis_increment = zeros(1, num_of_points);

% Normalized axis increment
normalized_axis_increment = 1/axes_interval;

% Iterate through number of points
for ii = 1:num_of_points
% Group of points
group_points = P(:, ii);

% Max and min value of each group
max_values(ii) = max(group_points);
min_values(ii) = min(group_points);
range = max_values(ii) - min_values(ii);

% Axis increment
axis_increment(ii) = range/axes_interval;

% Normalize points to range from [0, 1]
P(:, ii) = (P(:, ii)-min(group_points))/range;

% Shift points by one axis increment
P(:, ii) = P(:, ii) + normalized_axis_increment;
end

%%% Polar Axes %%%
% Polar increments
polar_increments = 2*pi/num_of_points;

% Normalized  max limit of axes
axes_limit = 1;

% Shift axes limit by one axis increment
axes_limit = axes_limit + normalized_axis_increment;

% Polar points
radius = [0; axes_limit];
theta = 0:polar_increments:2*pi;

% Convert polar to cartesian coordinates
[x_axes, y_axes] = pol2cart(theta, radius);

% Plot polar axes
grey = [1, 1, 1] * 0.5;
h = line(x_axes, y_axes,...
'LineWidth', 1,...
'Color', grey);

% Iterate through all the line handles
for ii = 1:length(h)
% Remove polar axes from legend
h(ii).Annotation.LegendInformation.IconDisplayStyle = 'off';
end

%%% Polar Isocurves %%%
% Shifted axes interval
shifted_axes_interval = axes_interval+1;

% Incremental radius
radius = (0:axes_limit/shifted_axes_interval:axes_limit)';

% Convert polar to cartesian coordinates
[x_isocurves, y_isocurves] = pol2cart(theta, radius);

% Plot polar isocurves
hold on;
h = plot(x_isocurves', y_isocurves',...
'LineWidth', 1,...
'Color', grey);

% Iterate through all the plot handles
for ii = 1:length(h)
% Remove polar isocurves from legend
h(ii).Annotation.LegendInformation.IconDisplayStyle = 'off';
end

%%% Figure Properties %%%
colors = [0, 0.4470, 0.7410;...
0.8500, 0.3250, 0.0980;...
0.9290, 0.6940, 0.1250;...
0.4940, 0.1840, 0.5560;...
0.4660, 0.6740, 0.1880;...
0.3010, 0.7450, 0.9330;...
0.6350, 0.0780, 0.1840];

% Repeat colors is necessary
repeat_colors = fix(row_of_points/size(colors, 1))+1;
colors = repmat(colors, repeat_colors, 1);

%%% Data Points %%%
% Iterate through all the rows
for ii = 1:row_of_points
% Convert polar to cartesian coordinates
[x_points, y_points] = pol2cart(theta(1:end-1), P(ii, :));

% Make points circular
x_circular = [x_points, x_points(1)];
y_circular = [y_points, y_points(1)];

% Plot data points
plot(x_circular, y_circular,...
'Color', colors(ii, :),...
'MarkerFaceColor', colors(ii, :),...
varargin{:});
end

%%% Axis Properties %%%
% Figure background
fig = gcf;
fig.Color = 'white';

% Iterate through all the number of points
for hh = 1:num_of_points
% Shifted min value
shifted_min_value = min_values(hh)-axis_increment(hh);

% Axis label for each row
row_axis_labels = (shifted_min_value:axis_increment(hh):max_values(hh))';

% Iterate through all the isocurve radius
for ii = 2:length(radius)
% Display axis text for each isocurve
text(x_isocurves(ii, hh), y_isocurves(ii, hh), sprintf(sprintf('%%.%if', axes_precision), row_axis_labels(ii)),...
'Units', 'Data',...
'Color', 'k',...
'FontSize', 10,...
'HorizontalAlignment', 'center',...
'VerticalAlignment', 'middle');
end
end

% Label points
x_label = x_isocurves(end, :);
y_label = y_isocurves(end, :);

% Shift axis label
shift_pos = 0.07;

% Iterate through each label
for ii = 1:num_of_points
% Angle of point in radians
theta_point = theta(ii);

% Find out which quadrant the point is in
if theta_point == 0
quadrant = 0;
elseif theta_point == pi/2
quadrant = 1.5;
elseif theta_point == pi
quadrant = 2.5;
elseif theta_point == 3*pi/2
quadrant = 3.5;
elseif theta_point == 2*pi
quadrant = 0;
elseif theta_point > 0 && theta_point < pi/2
quadrant = 1;
elseif theta_point > pi/2 && theta_point < pi
quadrant = 2;
elseif theta_point > pi && theta_point < 3*pi/2
quadrant = 3;
elseif theta_point > 3*pi/2 && theta_point < 2*pi
quadrant = 4;
end

% Adjust text alignment information depending on quadrant
switch quadrant
case 0
horz_align = 'left';
vert_align = 'middle';
x_pos = shift_pos;
y_pos = 0;
case 1
horz_align = 'left';
vert_align = 'bottom';
x_pos = shift_pos;
y_pos = shift_pos;
case 1.5
horz_align = 'center';
vert_align = 'bottom';
x_pos = 0;
y_pos = shift_pos;
case 2
horz_align = 'right';
vert_align = 'bottom';
x_pos = -shift_pos;
y_pos = shift_pos;
case 2.5
horz_align = 'right';
vert_align = 'middle';
x_pos = -shift_pos;
y_pos = 0;
case 3
horz_align = 'right';
vert_align = 'top';
x_pos = -shift_pos;
y_pos = -shift_pos;
case 3.5
horz_align = 'center';
vert_align = 'top';
x_pos = 0;
y_pos = -shift_pos;
case 4
horz_align = 'left';
vert_align = 'top';
x_pos = shift_pos;
y_pos = -shift_pos;
end

% Display text label
text(x_label(ii)+x_pos, y_label(ii)+y_pos, P_labels{ii},...
'Units', 'Data',...
'HorizontalAlignment', horz_align,...
'VerticalAlignment', vert_align,...
'EdgeColor', 'k',...
'BackgroundColor', 'w');
end

% Axis limits
axis square;
axis([-axes_limit, axes_limit, -axes_limit, axes_limit]);
axis off;
end

# 2. 多维数据可视化之气泡图

function [lh, th] = bubbleplot(x, y, z, siz, col, shape, varargin)
% BUBBLEPLOT produces a scatter plot that enables the visualization of upto
% 6-dimensional data. The dimensions used for displaying data include the
% X, Y and Z coordinates, the marker size, color and shape.
%
% USAGE:
% BUBBLEPLOT(x, y, z, siz, col, shape)
%    draws a 3D bubble plot. See input parameter description below.
%
% BUBBLEPLOT(x, y, [], siz, col, shape)
%    draws a 2D bubble plot.
%
% BUBBLEPLOT(..., textarray)
%    enables you to pass in a cell array of strings to annotate each point
%    on the plot. By default the strings are displayed as text labels as well
%    as stored in the UserData property of the line objects
%
% BUBBLEPLOT(..., textarray, 'ShowText', false)
%    will not display the text on screen, but will store it in the user
%    data property. This can be useful when creating a custom data tip.
%
% [hLine, hText] = BUBBLEPLOT(...)
%    returns a vector of line handles to the points in the plot and
%    (if appropriate) a vector of handles to the text objects on the
%    screen.
%
% INPUT PARAMETERS:
% The inputs should be vectors of the same length, with the following
% requirements:
%  Input     Required     Default-Value         Type
% x, y, z      Yes             N/A          Numerical (Continuous or discrete)
%   siz         No              8           Numerical (Continuous or discrete)
%   col         No           col = z        Numerical or Categorical*
%  shape        No             'o'          Categorical* (upto 13 unique discrete values)
%
% NOTES:
% * "Categorical" variables can either be numeric with discrete values or
%   non-numeric data types that support a "UNIQUE" method. Examples of this
%   can be a cell array of strings, a nominal array or ordinal array.
%
% * The siz variable is normalized to a marker size range of 3 to 20. To
%   specify a custom size range use the optional parameter
%   'markerSizeLimits'. Example: BUBBLEPLOT(..., 'MarkerSizeLimits', [5 32])
%
% * The shape variable can also be a character that represents a marker
%   shape to be used for all points
%
% * If col is a categorical variable, ensure it is integer-valued so that
%   it is handled correctly. If it is not integer valued, BUBBLEPLOT will
%   check to see if the number of unique values is less than 10% of the
%   length of the vector and use that to determine if the variable is
%   categorical. The colors used to depict categorical data are evenly
%   spaced (1 color level per unique category/label). However if col is
%   not categorical, its values are simply scaled to different values in
%   the colormap
%
% * The default font size used to display the text labels is 8 pt with a
%   left alignment. Use the input arguments 'FontSize' and 'Alignment' to
%   control these properties.
%   Example: BUBBLEPLOT(..., 'FontSize', 6, 'Alignment', 'center')
%
% * You can specify a custom colormap using the Colormap argument. The
%   parameter can be a string (eg. 'cool'), a function handle (eg. @jet) or
%   an N-by-3 matrix of color RGB levels.
%   Example: BUBBLEPLOT(..., 'ColorMap', cmap)

% Copyright 2009-2014 The MathWorks, Inc.

%% Parse input params and defaults

% Check number of input arguments
error(nargchk(2,10,nargin,'struct'));

% Default z
if nargin < 3
z = [];
end

% Default size
if nargin < 4 || isempty(siz)
siz = 8;
end

if nargin < 5 || isempty(col)
col = z;
end

if nargin < 6 || isempty(shape)
shape = 'o';
end

p = inputParser;
p.addOptional('Text',{},@(x)iscellstr(x)||(ischar(x)&&size(x,1)>1)||(~ischar(x)&&length(x)>1));
p.addParamValue('ShowText',true);
p.addParamValue('FontSize',8);
p.addParamValue('Alignment', 'left');
p.addParamValue('MarkerSizeLimits',[3 20]);
p.addParamValue('ColorMap',@cool);
p.parse(varargin{:});
desctext = p.Results.Text;
showText = p.Results.ShowText;
if isempty(desctext), showText = false; end
fontSize = p.Results.FontSize;
alignment = p.Results.Alignment;
colmapfun = p.Results.ColorMap;
markerSizeLimits = p.Results.MarkerSizeLimits;

%% Determine marker colors
if ischar(colmapfun)
colmapfun = str2func(colmapfun);
elseif isnumeric(colmapfun)
colmapfun = @(x)colmapfun(1:min(x,end),:);
end

if isempty(col)
col = zeros(size(x));
end
[uniqueCols, gar, colInd] = unique(col);
if isinteger(col) || isa(col,'categorical') || iscell(col) || length(uniqueCols)<=.1*length(col) || all(round(col)==col) % Is col categorical
% Generate a colormap with one level per unique entry in col
colmap = colmapfun(length(uniqueCols));
else
% Scale the color values to span the colormap
colmap = colmapfun(256);
mx = max(col);
n = min(col);
if mx == n, mx = n + 1; end
colInd = (col-n)/(mx-n)*(size(colmap,1)-1)+1;
end
try
color = colmap(round(colInd),:);
catch %#ok<CTCH>
error('The custom colormap must have at least %d levels', max(colInd));
end

%% Determine marker shape
if ischar(shape)
markertype = repmat(shape(1),size(x));
else
markerseq = 'osd^><vph.*+x';
[uniqueShapes, gar, shapeInd] = unique(shape);
if length(uniqueShapes)>length(markerseq)
error('BubblePlot can only support 13 unique shapes');
end
markertype = markerseq(shapeInd);
end

%% Determine marker size
if isscalar(siz)
siz = repmat(siz, size(x));
markersize = siz;
else % Map the siz variable to a markersize between a minimum and maximum
minsize = markerSizeLimits(1);
maxsize = markerSizeLimits(2);
markersize = (siz - min(siz))/(max(siz)-min(siz))*(maxsize - minsize)+minsize;
end

%% Clean up data - handle NaNs
markersize(isnan(markersize)) = .01; % These will not be drawn as regular markers, just pixel points

%isnan(x) | isnan(y) | isnan(z) | isnan(col) |

%% Plot data
% Create structure to store original data in every graphics object (for
% subsequent retrieval, eg: with data tip)

pointData = struct('x',num2cell(x),'y',num2cell(y),'siz',num2cell(siz),'col',num2cell(col),...
'shape',num2cell(shape));

if nargin > 6 && ~isempty(desctext)
if ~iscellstr(desctext)
desctext = cellstr(desctext);
end
[pointData.text] = desctext{:};
end

if isempty(z)
plotfun = @plot;
%plotfun = @patch;
%zarg = {color(1,:)};
zarg = {};
else
plotfun = @plot3;
zarg = {z(1)};
zdata = num2cell(z);
[pointData.z] = zdata{:};
end

lh = zeros(1,length(x)); % Line Handles
lh(1) = customPlot(plotfun, pointData(1), color(1,:), markersize(1), markertype(1), x(1), y(1), zarg{:});

for i = 2:length(lh)
if isempty(z), zarg = {}; else zarg = {z(i)}; end
%if isempty(z), zarg = {color(i,:)}; else zarg = {z(i)}; end
lh(i) = customPlot(@line, pointData(i), color(i,:), markersize(i), markertype(i), x(i), y(i), zarg{:});
%lh(i) = customPlot(@patch, pointData(i), color(i,:), markersize(i), markertype(i), x(i), y(i), zarg{:});
end

if showText
hAxes = get(lh(1),'Parent');
offset = diff(get(hAxes,'Ylim'))*.01;
if isempty(z)
z = zeros(size(x));
end
th = text(x, y-offset, z, desctext, 'Fontsize', fontSize, 'HorizontalAlignment', alignment);
lims = get(hAxes,{'XLim','YLim','ZLim'});
lims = vertcat(lims{:});
factor = fontSize.*diff(lims,[],2);
addlistener(hAxes,{'XLim','YLim'},'PostSet',@(obj,evdata)resizeText(hAxes, th, y, factor));
%addlistener(get(hAxes,'Parent'),'Resize',@(obj,evdata)resizeText(hAxes, th));
else
th = [];
end

function lh = customPlot(funh, pointData, c, siz, markertype, varargin)
lh = funh(varargin{:});
set(lh, 'Marker', markertype,...
'LineStyle', 'none', 'Color', c, ...
'MarkerFaceColor', c, ...
'MarkerEdgeColor', [0 0 0], 'MarkerSize', siz,...
'UserData', struct('Point',pointData));

%     lh = patch('XData',x(i),'YData', y(i), 'ZData', z(i), 'Marker', 'o',...
%     'LineStyle', 'none', 'CData', color, 'MarkerFaceColor', c, ...
%     'MarkerEdgeColor', [0 0 0], 'MarkerSize', siz2(i), 'FaceAlpha', .4, 'EdgeAlpha', .2, ...
%     'UserData', data);

function resizeText(hAxes, hText, y, factor) %#ok<*INUSD>
lims = get(hAxes,{'XLim','YLim','ZLim'});
lims = vertcat(lims{:});
% Uncomment following to update fontsize
% newfs = min([factor(1:2)./diff(lims(1:2,:),[],2) ; 24]);
% set(hText,'FontSize',newfs);

% Update position
offset = diff(get(hAxes,'Ylim'))*.01;
p = get(hText,'Position');
p = vertcat(p{:});
outofbounds = any(bsxfun(@gt,p,lims(:,2)') | bsxfun(@lt,p,lims(:,1)'), 2);
set(hText(outofbounds),'Visible','off');
set(hText(~outofbounds),'Visible','on');

% Adjust offsets
p(:,2) = y - offset;
for i = 1:length(p)
set(hText(i),'Position',p(i,:));
end

## 2.1 加载数据

load carsmall
Origin = cellstr(Origin);

## 2.2 3D气泡图

• X: Acceleration (continuous)
• Y: Horsepower (continuous)
• Z: MPG (continuous)
• Size: Weight (continuous)
• Color: Model_Year (discrete, ordinal)
• Shape: Origin
clf
bubbleplot(Acceleration, Horsepower, MPG, Weight, Model_Year, Origin);
grid on
xlabel('Acceleration');ylabel('Horsepower');zlabel('MPG');

## 2.3 可点击图例

function varargout = clickableLegend(varargin)
% clickableLegend  Interactive legend for toggling or highlighting graphics
%
% clickableLegend is a wrapper around the LEGEND function that provides
% interactive display toggling or highlighting of lines or patches in a MATLAB
% plot. It enables you to,
% * Toggle (hide/show) a graphics object (or group) by clicking on an
%   associated text label in the legend
% * Highlight and identify a graphics object (or group) by clicking it.
%
% Its usage is the same as the <a href="matlab: help legend">LEGEND</a> function with additional
% optional parameters. For further information please see the LEGEND documentation.
%
% ADDITIONAL ARGUMENTS specific to clickableLegend:
% These are passed in as parameter-value pairs
%
% * groups: A vector specifying the group membership for every line object.
%   The grouping parameter lets you have a group of lines represented and
%   controlled by one entry in the legend. This can be useful if you would
%   like to highlight or hide a group of lines by clicking on one legend entry.
%   CONSIDERATIONS:
%   # The number of unique entries in the group vector must match the
%     number of strings in the legend
%   # When passing a vector of line/patch handles as the first input
%     argument, the vector should contain all lines/patches whose group
%     membership is included in the group vector. ie. the length of the
%     vector of handles must match that of the length of the group vector.
%
% * displayedLines: A vector of indices corresponding to the lines or groups that
%   should be displayed initially. This option is useful if there are too
%   many lines in the figure and you are only interested in looking at a
%   few at first.
%   Example: clickableLegend(..., 'displayedLines', [4 5 6])
%
% * plotOptions: A cell array of parameter value pairs that define
%   properties of the graphics objects in the legend. This can be useful,
%   for example, to ensure consistent marker sizes within the legend.
%
% Notes:
% 1. If you save the figure and re-load it, the toggling functionality
% is not automatically re-enabled. To restore it, simply call clickableLegend
% with no arguments.
%
% 2. To prevent the axis from automatically scaling every time a line is
% turned on and off, issue the command: axis manual
%
% Example 1:
% z = peaks(100);
% plot(z(:,26:5:50))
% grid on;
% axis manual;
% clickableLegend({'Line1','Line2','Line3','Line4','Line5'}, 'Location', 'NorthWest');
%
% Example 2:
% f = plot([1:10;1:2:20]','x'); hold on;
% g = plot(sin([1:10;1:2:20]'),'r-');
% h = plot(11:20,rand(5,10)*5,'b:');
% clickableLegend([f;g;h], {'Line1','Line2','Line3'},...
%   'groups', [1 1 2 2 3 3 3 3 3], 'displayedLines', [2 3]);
%
% hgsave(gcf, 'testfig.fig');
% hgload testfig.fig
% clickableLegend
%
% See also legend, clickableLegend_examples

% Copyright 2009-2014 MathWorks, Inc.

% Extract any arguments for clickableLegend
[dispinds, groupmem, plotOptions, varargin] = ...
extractOptionalArgs(varargin{:});

% Process group memberships
[groups, plotObj, varargin] = processGroups(groupmem, varargin{:});

% Create legend
[varargout{1:nargout(@legend)}] = legend(varargin{:});

% Extract what is needed for the rest of the function and fix varargout
[leghan, objhan, plothan] = varargout{1:3};
% objhan: strings
% plothan: graphics objects
varargout = varargout(1:nargout);

if isempty(groupmem) % Default group membership
groupmem = 1:length(plothan);
plotObj = plothan;
groups = groupmem;
end

if ~isempty(dispinds) % DisplayedLines parameter was specified
hidden = true(1, length(plothan));
dispinds(dispinds>length(plothan)) = [];
hidden(dispinds) = false;
end

% Set the callbacks & plot options
for i = 1:length(plothan)
set(objhan(i), 'HitTest', 'on', 'ButtonDownFcn',...
@(varargin)togglevisibility(objhan(i),plotObj(groupmem==groups(i))),...
'UserData', true);
if ~isempty(dispinds) && hidden(i)
togglevisibility(objhan(i), plotObj(groupmem==groups(i)));
end
set(plotObj(groupmem==groups(i)), 'HitTest', 'on', 'ButtonDownFcn', ...
@(varargin)highlightObject(objhan(i),plothan(i),...
plotObj(groupmem==groups(i)),plotOptions),...
'UserData', false);
if ~isempty(plotOptions)
set(plothan(i), plotOptions{:});
end
end

function togglevisibility(hObject, obj)
if get(hObject, 'UserData') % It is on, turn it off
set(hObject, 'UserData', false);
set(obj,'HitTest','off','Visible','off','handlevisibility','off');
else
set(hObject, 'UserData', true);
set(obj, 'HitTest','on','visible','on','handlevisibility','on');
end

function highlightObject(lTextObj, lMarkerObj, plotObj, plotOptions)
lw = get(plotObj,'LineWidth');
if ~iscell(lw), lw = {lw}; end;
ms = get(plotObj,'MarkerSize');
if ~iscell(ms), ms = {ms}; end;

if ~get(plotObj(1), 'UserData') % It is not selected, highlight it
%set(hObject, 'FontWeight', 'bold');
set(lTextObj, 'EdgeColor', 'k');
set(plotObj, {'LineWidth', 'MarkerSize'}, [cellfun(@(x)x+2, lw, 'Uniformoutput', false) cellfun(@(x)x+2, ms, 'uniformoutput', false)]);
set(plotObj, 'UserData', true);
else
%set(hObject, 'FontWeight', 'normal');
set(lTextObj, 'EdgeColor', 'none');
set(plotObj, {'LineWidth', 'MarkerSize'}, [cellfun(@(x)x-2, lw, 'Uniformoutput', false) cellfun(@(x)x-2, ms, 'uniformoutput', false)]);
set(plotObj, 'UserData', false);
end
if ~isempty(plotOptions)
set(lMarkerObj, plotOptions{:});
end

function [dispinds, groupmem, plotOpt, varargin] = extractOptionalArgs(varargin)
% Extract the displayedlines and/or groups arguments if specified

ind = find(strcmpi(varargin,'DisplayedLines'));
if ~isempty(ind)
assert(ind<nargin, 'The DisplayedLines parameter value must be specified');
dispinds = varargin{ind+1};
varargin(ind:ind+1) = [];
else
dispinds = [];
end

ind = find(strcmpi(varargin,'groups'));
if ~isempty(ind)
assert(ind < nargin, 'The groups parameter value must be specified');
groupmem = varargin{ind+1};
varargin(ind:ind+1) = [];
else
groupmem = [];
end

ind = find(strcmpi(varargin,'plotoptions'));
if ~isempty(ind)
assert(ind < nargin, 'The plotOptions parameter value must be specified');
plotOpt = varargin{ind+1};
varargin(ind:ind+1) = [];
else
plotOpt = {};
end

function [groups, obj, varargin] = processGroups(groupmem, varargin)
if isempty(groupmem)
groups = []; obj = [];
return;
end
if iscellstr(groupmem)
groupmem = categorical(groupmem);
end
groups = unique(groupmem);
firstmem = zeros(size(groups));
if nargin > 1 && ishandle(varargin{1}(1))
if strcmpi(get(varargin{1}(1),'Type'),'axes')
hAxes = varargin{1}(1);
obj = flipud([findobj(hAxes,'Type','line');findobj(hAxes,'Type','patch')]);
else % It's a line/patch
obj = varargin{1};
[~,firstmem] = ismember(groups, groupmem);
%for i = 1:length(groups)
%    firstmem(i) = find(groupmem==groups(i),1);
%end
varargin{1} = obj(firstmem);
end
else
hAxes = gca;
obj = flipud([findobj(hAxes,'Type','line');findobj(hAxes,'Type','patch')]);
end

实例代码如下：

clf
h = bubbleplot(Acceleration, Horsepower, MPG, Weight, Model_Year, Origin);
grid on
xlabel('Acceleration');ylabel('Horsepower');zlabel('MPG');

clickableLegend(h, unique(Origin), 'groups', Origin, 'plotOptions', ...
{'MarkerSize', 8, 'MarkerFaceColor', 'c'});

## 2.4 七维数据的3D可视化效果图

• X: Acceleration (continuous)
• Y: Horsepower (continuous)
• Z: MPG (continuous)
• Size: Weight (continuous)
• Color: Model_Year (discrete, ordinal)
• Shape: Cylinders
• Text: Origin
clf
bubbleplot(Acceleration, Horsepower, MPG, Weight, Model_Year, Cylinders,...
Origin, 'fontSize',6);
grid on
xlabel('Acceleration');ylabel('Horsepower');zlabel('MPG');

## 2.5 五维数据的2D可视化效果图

• X: Horsepower (continuous)
• Y: MPG (continuous)
• Size: Acceleration (continuous)
• Color: Displacement (continuous)
• Shape: Origin
• Text: Manufacturer
clf
h = bubbleplot(Horsepower, MPG, [], Acceleration, Displacement, Origin,...
Mfg, 'fontSize', 6);
xlabel('Horsepower');ylabel('MPG');
grid on;
clickableLegend(h, unique(Origin), 'groups', Origin, 'plotOptions', ...
{'MarkerSize', 8, 'MarkerFaceColor', 'c'});

03-06
02-15 5463
08-29 4448
04-30 2万+
04-30 1735
03-09
12-24 3100
10-25
11-21 2548
08-27
03-25 7718
11-29 1870
©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客