在绘制5维散点图的时候,可以利用颜色代表第4维度的信息,利用气泡的大小来表示第5维度的信息。然而,这里有两个问题:
- 如何绘制出一个可以标注气泡大小的legend;
- 如何在一张图上显示两个Legend。
1. legendScatter
Matlab官网上给出了一个绘制可以标注气泡大小的legend的实现,其具体说明如下:
This function aims to simplify the creation of a legend for scatter plots. The function will plot a legend on current axis with the right markersize proportion.
该方法旨在简化散点图的legend的创建,它会在当前坐标系上显示对应的尺度的气泡标记,效果如下图所示。
function [hleg,hobj]=legendScatter(TextCell,SizeDim,Factor,LinSpec)
%% LEGENDSCATTER: workaround for R2016a and later for scatter plot legend.
% This function aims to simplify the creation of a legend for scatter plots.
% The function will plot a legend on current axis with the right
% markersize proportion.
% NB. From version 1.0.5 is added the compatibility with previous MATLAB
% version.
%
% Inputs: - TextCell: a cell array containing the legend-entry text.
% WARNING: THE FIRST CELL IS THE TITLE !!!
% - SizeDim: the ''MarkerSize'' dimension for each entry.
% WARNING: length(SizeDim)==length(TextCell)-1 !!!
% - Factor: normaling factor for enlarge the marker size in
% a linear way. (MarkerSize*sqrt(Factor)
% - LinSpec: specify the marker-string.
%
% EXAMPLE: -----------------------------------------------------
% Factor=1.5;
% A=[1,1,1;
% 2,2,2;
% 3,3,3;
% 4,4,4;
% 5,5,5;
% 6,6,6;
% 7,7,7;
% 8,8,8;
% 9,9,9;
% 10,10,10];
%
% sh=scatter(A(:,1),A(:,2),(A(:,3).^2)*Factor,'ok');
% %scattersize==MarkerSize*sqrt(Factor)pt)
% leg=LEGENDSCATTER({'SIZE','1','2','3','4','5', ...
% '6','7','8','9','10'},[1:1:10],Factor,'ok');
% leg.Location='NorthWest'; axis([0,11,0,11])
% -----------------------------------------------------
%
% VERSION:1.0.5
% AUTHOR: Matteo Bagagli - ETH-Zurich // Oct. 2016
% MAIL: [email protected]
%% FAKE PLOTS
hold on
hplt=zeros(length(TextCell),1)';
for ii=1:length(TextCell)
hplt(ii)=plot(NaN,NaN,LinSpec);
end
hold off
%% WORK
[hleg,hobj]=legend(hplt,TextCell,'Units','points');
drawnow % To update the figure and the legend
idx=(length(TextCell)+4):2:length(hobj); % Skip text and TITLE MARKER
v=version;
if str2double(v(1)) >= 9 % MATLAB v9.0 and higher
% Title
hobj(1).FontWeight='bold';
ActPos=hobj(1).Position;
hobj(1).Position=[0.5,ActPos(2),ActPos(3)];
hobj(1).HorizontalAlignment='center';
hobj(1).FontSize=11;
hobj(length(TextCell)+2).Marker='none';
% Body
for ii=1:length(idx)
hobj(idx(ii)).MarkerSize=SizeDim(ii)*sqrt(Factor);
end
else % MATLAB v8 and lower
% Title
set(hobj(1),'FontWeight','bold');
ActPos=get(hobj(1),'Position');
set(hobj(1),'Position',[0.5,ActPos(2),ActPos(3)]);
set(hobj(1),'HorizontalAlignment','center');
set(hobj(1),'FontSize',11);
set(hobj(length(TextCell)+2),'Marker','none');
% Body
for ii=1:length(idx)
set(hobj(idx(ii)),'MarkerSize',SizeDim(ii)*sqrt(Factor));
end
end % end switch version
end % EndMain
2. 使用方法
接下来,我们就需要解决如何同时显示两个legend了。以用来分别标注第4维度和第5维度的信息。如下所示,我们用颜色代表第4维度的数据,用气泡大小表示第5维度的数据。
具体效果如上图所示,通过对fig进行稍微编辑,可以达到想要的效果。其具体实现如下所示。
%% PlatEMO下多维PF面可视化
function [ ] = Draw_bubble()
problem = 'DMOPs4_OS'; %问题
PF=load(sprintf('F:\\多目标优化论文\\实验——代码\\PlatEMO v1.5 (2017-12)\\Data/%s/%s.mat',problem,problem));
Factor = 1.5;//笔者需要自己调整
sz_base = 35;
%绘制气泡图
data = PF.PF.objs;
x = data(:,1)';
y = data(:,2)';
z = data(:,3)';
%计算能耗等级
energe_level = unique(data(:,5));
level = zeros(1,size(data,1));
for i=1:size(data,1)
for j=1:length(energe_level)
if data(i,5) == energe_level(j)
k=j;
break;
end
end
level(i) = k;
end
SizeDim = level * sz_base;
u = SizeDim * sqrt(Factor); %sqrt(Factor) * level * sz_base;
%生成颜色
gnums = unique(data(:,4));
c = parula(length(gnums));
c = fliplr(c')';
%根据使用的罐的个数绘制图像
figure;
g_num = data(:,4);
legendtext = cell(1,length(gnums));
for i=1:length(gnums)
ind = find(g_num== gnums(i)); %供油罐个数为tmp(i)的记录下标
scatter3(x(ind),y(ind),z(ind),u(ind),c(i,:),'fill');%颜色是用罐个数,气泡大小是切换次数
legendtext{i} = num2str(gnums(i));
hold on;
end
legend(legendtext);
title('Visualization of Prato front');
range = [min(x), max(x), min(y), max(y), min(z), max(z)];
axis(range);% 坐标轴的显示范围
xlabel('J_\alpha');% x轴名称、字体及大小
ylabel('J_\beta');% y轴名称、字体及大小
zlabel('J_\gamma');% z轴名称、字体及大小
axes('position',get(gca,'position'),'visible','off');
sizeCC = linspace(5,25,10);
legendScatter({'','150','160','170','180','190','200','210','220','230','240'},sizeCC,Factor,'ob');
end
注意,因为一般在绘制第二个legend时,Matlab默认会将第一个legend删除,因此,在绘制第二个legend之前,需要加入如下语句:
axes('position',get(gca,'position'),'visible','off');