ExcelPro的图表博客的作者刘老师最近用EXCEL做出了一个非常炫的图叫堆积式南丁格尔玫瑰图,还叫半径不等的扇形图、极区图 南丁格尔玫瑰图、风玫瑰图等等,据说最早是一个叫南丁格尔的护士最早使用的,她自己叫这个图为“鸡冠花图(coxcomb)”,一种圆形的直方图,除了讲述用EXCEL的具体做法,还对此图从专业方面给出了评价,指出了该图的优缺点和适用场合。具体介绍见刘老师的博文一,博文二。

python实现南丁格尔玫瑰图代码 南丁格尔玫瑰图又称为_SAS

这种图在excel里面是雷达图拼凑起来的,具体说是360个,当然越多图越圆,我没有试过。下面我给出用SAS代码实现的一种方法,虽然还没完成,但是大概差不多了,从构思到半成型花了差不多一天的时间,思路花了三分之一的时间,大部分时间在调试代码(好久没用,不熟练。)

下面给出我的思路:

全部用annotate完成:1,首先用PIE函数画出整个轮廓,包括外面的光圈,pie图和中心的圆;2,然后用piexy函数对各片pie进行标注;3,最后对每个pie的不同部分用point和draw函数进行标注,这里只完成了前两步,后面一步在(下)里面完成,技巧已经在包含前两步里面。

着手编程时,参考了Robslink的代码,当然,代码需要改动很大,并且原图的配色确实很逊,和上面的图没法比。


python实现南丁格尔玫瑰图代码 南丁格尔玫瑰图又称为_ci_02

本图代码见底下附。

点评:

1,对于这样的大型图,excelpro认为用excel做的是难度是5星,实用性为3星,我认为酷劲也该给个五星。

2,excel需要构造一堆数来完成这个图形, SAS也需要一堆代码来搭积木。excel的优点就是实时可见,随时调整,而SAS则需要修改好代码后,反复运行调试参数;不过SAS还有个优点,就是一旦完成,自动化程度高。比如说下次碰到的指标为10个,比这次少一个,怎么办?excel的话,需要重新构造10块饼的数据,从头再来,而SAS就不需要,直接运行即可,因为里面用到宏直接传递这些绘图信息。     当然excel里面也有VBA,也可以自动化的功能,当然这个工作量就剧增了。

问题:

1,圆心的填色“facebook”处好呆板,SAS里面好像没有现成的那种颜色,需要用修改GTL的方法得到那种渲染效果的颜色,不过没有尝试。

2,几次遇到SAS绘图的清晰度问题,也就是怎么要得到高dpi的图,尝试了几种方法,都没有得到想要的。怎么保持图片大小不变,而清晰度增加,换个角度怎么让SAS出图片尺寸小,文件非常大

%let name=rose2;
FILENAME file "c:\";
data ex;
input index $4.value col $;
col="CX"||col;
cards;
a30 989898
a70 353535
b41 808080
b59 353535
c88 636466
c12 353537
d54 385599
d46 2E4A7A
e13 375299
e34 2D4978
e30 637798
e12 8395BB
e7 BACAE2
e4 8F9CA8
f11 375299
f29 2D4978
f23 637798
f18 8395BB
f12 BACAE2
f7 8F9CA8
g21 375299
g28 2D4978
g22 637798
g29 8395BB
h70 F1F1F1
h30 353533
i12 E6E6E6
i88 353535
j51 CCCCCC
j49 353535
k40 B3B3B3
k60 353535
;
run;
/*构造控制绘图参数 PIE函数的半径rad,起始角和角度ang */
data ex2;
set ex nobs=max;
by index;
retain rad ang 0;
if first.index then
do ; rad=1;ang+1; output; end;
else do; rad+1;output; end;
if _N_=max then do; call symput("piece", ang); end;
%put &piece.;
run;
/*设置最大饼环的半径为整个图的百分比*/
%let radius=25;
data pies; set ex2;
by index;
length style function color $ 12;
xsys='3'; ysys='3'; hsys='3';
x=50; y=50; /* 定位圆心 */
function = 'PIE';
style = 'SOLID';
if first.index then do sizev = value; end;
else do ; sizev + value; end;
size=(&radius.*((sizev+40)/100)); /*最大半径为 &radius% */
angle = 10;
angle =angle + ((ang-1) / &piece.)*360;
rotate = (1/ &piece.)*360;
/*angle+((1/&piece.)*360); start angle for this slice */
/*if first=1 then angle=0; */
color=col;
output;
run;
proc sort data=pies out=pies;
by index decending sizev;
run;
/* 中心空白圆 */
data hole1; set ex2;
length style function color $ 12;
xsys='3'; ysys='3'; hsys='3';
x=50;
y=50;
function='PIE';
style='SOLID';
angle=0;
line=1;
rotate=360;
size=(&radius.*((39)/100));
color='CX2F3338';
output;
run;
data hole2; set ex2;
length style function color $ 12;
xsys='3'; ysys='3'; hsys='3';
x=50;
y=50;
function='PIE';
style='SOLID';
angle=0;
line=1;
rotate=360;
size=(&radius.*((36)/100));
color='CX415D8E';
output;
run;
/* 天 使 圈 */
data circle1; set ex2;
length style function color $ 12;
xsys='3'; ysys='3'; hsys='3';
x=50;
y=50;
function='PIE';
style='SOLID';
angle=0;
line=1;
rotate=360;
size=(&radius.*((148)/100));
color='CX2E2E2E';
output;
run;
data circle2; set ex2;
length style function color $ 12;
xsys='3'; ysys='3'; hsys='3';
x=50;
y=50;
function='PIE';
style='SOLID';
angle=0;
line=1;
rotate=360;
size=(&radius.*((145)/100));
color='CX232323';
output;
run;
/* 饼周围的外线 */
data outlines; set pies hole1;
style='EMPTY';
color="CX6C6C6C";
line=3;
run;
/* 标注每个 PIE */
data slices; set pies; by index;
if first.index then output;
run;
data slices; set slices;
length text $10;
/* 定位到PIE的正上方的角度 */
function='piexy'; angle=angle+rotate*.5;
/* 定位到PIE的正上方的位置距离 */
size=5; output;
/* 转换坐标 */
function='cntl2txt'; output;
/* 在定义好的地方进行标注 */
function='label'; text=index||index||index; angle=0; rotate=0; color='CX776122';
style='"arial/bo"'; size=3; x=.; y=.; position='5';
output;
run;
/* 标注中心 地方 */
data center;
length style function color $ 12;
length text $12;
xsys='3'; ysys='3'; hsys='3';
x=50;
y=50;
function='LABEL';
color='CXF1F9FF';
text='facebook';
position='B';
style='"arial/bo"'; size=3.5;
output;
run;
/*data anno; set circle1 circle2 center pies outlines hole1 hole2 slices ; run;*/
data anno; set circle1 circle2 center pies outlines hole1 hole2 slices; run;
ODS LISTING close ;
ODS HTML path=file body="&name..htm" ;
goptions reset=all noborder
xpixels=4000 xmax=3in ypixels=4000 ymax=3in
device=JPEG300 gsfname=file cback=CX242424;
proc ganno annotate=anno name="&name"; ;
run;
quit;
ods HTML CLOSE;
ODS LISTING ;