Please ignore the gray square in legend, this can be fixed by 'legendItem'.
This is the picture I wanted. The percent of the car produced have been displayed by categories ( the cars' Type and DriveTrain).
But, when I generated the figure by statgraph 'barchart_with_no_lattice', the tick values of y axis were not displayed as expected. The code is as follows:
About the format of 'cateparam.', please refer to the last part.
proc template;
define statgraph barchart_with_no_lattice;
begingraph /border=false;
discreteattrmap name='colors' / ignorecase=true;
value "Asia" / lineattrs=(color=&color1.) fillattrs=(color=&color1.);
value "Europe" / lineattrs=(color=&color2.) fillattrs=(color=&color2.);
value "USA" / lineattrs=(color=&color3.) fillattrs=(color=&color3.);
enddiscreteattrmap;
discreteattrvar attrvar=barcolors var=origin attrmap='colors';
layout overlay /
yaxisopts = (display=(ticks tickvalues)
linearopts=(tickvaluesequence=(start=&xmin. end=&xmax. increment=1) tickvalueformat=cateparam.))
xaxisopts = (display=(ticks tickvalues)
linearopts=(viewmax=100 viewmin=0 tickvaluesequence=(start=0 end=100 increment=10)));
barchart category=paramn response=percent / name='origin' group=barcolors orient=horizontal grouporder=data
groupdisplay=stack display=(fill);
discretelegend 'origin';
endlayout;
endgraph;
end;
run;
ods graphics on / reset outputfmt=png imagename='barchart_with_no_lattice';
proc sgrender data=type_new template=barchart_with_no_lattice;
run;
The figure generated by 'barchart_with_no_lattice':
Please ignore the gray square in legend, this can be fixed by 'legendItem'.
And, I used the 'lattice' to display the text for a temporary solution, left and right. In the left figure, I wantted to display the text that should be showed in tick values. Suddendly, I found the TickValueFormat was working as expected, so the width of left figure was set to 0, finally the first figure above was generated. the code I used as follows:
proc template;
define statgraph barchart_with_lattice;
begingraph /border=false;
discreteattrmap name='colors' / ignorecase=true;
value "Asia" / lineattrs=(color=&color1.) fillattrs=(color=&color1.);
value "Europe" / lineattrs=(color=&color2.) fillattrs=(color=&color2.);
value "USA" / lineattrs=(color=&color3.) fillattrs=(color=&color3.);
enddiscreteattrmap;
discreteattrvar attrvar=barcolors var=origin attrmap='colors';
layout lattice / columns=2 columnweights=(0 1.0) rowdatarange=union;
layout overlay / walldisplay=none yaxisopts=(display=none) xaxisopts=(display=none);
scatterplot y=paramn x=param /markercharacterposition=right;
endlayout;
layout overlay /
yaxisopts=(display=(ticks tickvalues)
linearopts=(tickvaluesequence=(start=&xmin. end=&xmax. increment=1) tickvalueformat=cateparam.))
xaxisopts=(display=(ticks tickvalues)
linearopts=(viewmax=100 viewmin=0 tickvaluesequence=(start=0 end=100 increment=10)));
barchart category=paramn response=percent / name='origin' group=barcolors orient=horizontal grouporder=data
groupdisplay=stack display=(fill);
discretelegend 'origin';
endlayout;
endlayout;
endgraph;
end;
run;
ods graphics on / reset outputfmt=png imagename='barchart_with_lattice';
proc sgrender data=type_new template=barchart_with_lattice;
run;
Did I miss something in 'barchart_with_no_lattice'? Why did not the TickValueFormat work?
Thanks for any information.
The data used by 'PROC SGRENDER' was generated by this code, dataset's name is 'type_new':
data cars;
set sashelp.cars;
format _all_;informat _all_;
run;
proc sql noprint;
create table type01_01 as
select distinct type,origin,count(distinct model) as count from cars group by type,origin;
create table type01_02 as
select distinct type,count(distinct model) as bign from cars group by type;
create table type01 as
select lds.*,rds.bign from type01_01 lds left join type01_02 rds on lds.type=rds.type;
quit;
proc sql noprint;
create table type02_01 as
select distinct drivetrain,origin,count(distinct model) as count from cars group by drivetrain,origin;
create table type02_02 as
select distinct drivetrain,count(distinct model) as bign from cars group by drivetrain;
create table type02 as
select lds.*,rds.bign from type02_01 lds left join type02_02 rds on lds.drivetrain=rds.drivetrain;
quit;
data type1;
length cate param $200 percent 8;
set type01(in=a) type02(in=b);
if a then cate='1st Category';
else cate='2nd Category';
param=coalescec(type,drivetrain);
percent=count/bign*100;
run;
proc sort;by cate param;run;
data type9;
set type1;
by cate param;
output;
if first.cate then do;
param=strip(cate);call missing(percent,origin);
output;
end;
run;
proc sort;by descending cate descending param;run;
data type_new;
length paramn 8;
retain paramn;
set type9;
by descending cate descending param;
if _n_=1 then paramn=0;
if first.param then paramn=paramn+1;
run;
The format and macro variables was generated by this code:
data format;
length fmtname $200 start 8 label type $200;
set type_new;
fmtname='cateparam';
start=paramn;
label=strip(param);
type='n';
keep fmtname start label type;
run;
proc sort data=format nodupkey;by start label;run;
proc format library=work cntlin=format;run;
proc sql noprint;
select min(start) into:xmin trimmed from format;
select max(start) into:xmax trimmed from format;
quit;
%put &xmin. &xmax.;
%let color1=vligb;
%let color2=liyg;
%let color3=lioy;
The full code also was uploaded by 'txt' in the attachment.
@ballardw is correct that the bar chart category axis is discrete by default, causing the TickValueFormat in the LINEAROPTS to be ignored. However, bar chart DO support linear category axes. So, if you set the Y axis explicitly to be TYPE=LINEAR, your format should be honored. Let us know if that works for you.
I don't think the base of bar charts can be considered "linear" as they are categorical. So I'm not surprised that LINEAROPTS applied to that axis misbehave. Kind of says so right in the syntax:
barchart category=<variable name>
The variable is categorical.
@Eric_Lee wrote:
Please ignore the gray square in legend, this can be fixed by 'legendItem'.
This is the picture I wanted. The percent of the car produced have been displayed by categories ( the cars' Type and DriveTrain).
But, when I generated the figure by statgraph 'barchart_with_no_lattice', the tick values of y axis were not displayed as expected. The code is as follows:
About the format of 'cateparam.', please refer to the last part.
proc template; define statgraph barchart_with_no_lattice; begingraph /border=false; discreteattrmap name='colors' / ignorecase=true; value "Asia" / lineattrs=(color=&color1.) fillattrs=(color=&color1.); value "Europe" / lineattrs=(color=&color2.) fillattrs=(color=&color2.); value "USA" / lineattrs=(color=&color3.) fillattrs=(color=&color3.); enddiscreteattrmap; discreteattrvar attrvar=barcolors var=origin attrmap='colors'; layout overlay / yaxisopts = (display=(ticks tickvalues) linearopts=(tickvaluesequence=(start=&xmin. end=&xmax. increment=1) tickvalueformat=cateparam.)) xaxisopts = (display=(ticks tickvalues) linearopts=(viewmax=100 viewmin=0 tickvaluesequence=(start=0 end=100 increment=10))); barchart category=paramn response=percent / name='origin' group=barcolors orient=horizontal grouporder=data groupdisplay=stack display=(fill); discretelegend 'origin'; endlayout; endgraph; end; run; ods graphics on / reset outputfmt=png imagename='barchart_with_no_lattice'; proc sgrender data=type_new template=barchart_with_no_lattice; run;
The figure generated by 'barchart_with_no_lattice':
Please ignore the gray square in legend, this can be fixed by 'legendItem'.
And, I used the 'lattice' to display the text for a temporary solution, left and right. In the left figure, I wantted to display the text that should be showed in tick values. Suddendly, I found the TickValueFormat was working as expected, so the width of left figure was set to 0, finally the first figure above was generated. the code I used as follows:
proc template; define statgraph barchart_with_lattice; begingraph /border=false; discreteattrmap name='colors' / ignorecase=true; value "Asia" / lineattrs=(color=&color1.) fillattrs=(color=&color1.); value "Europe" / lineattrs=(color=&color2.) fillattrs=(color=&color2.); value "USA" / lineattrs=(color=&color3.) fillattrs=(color=&color3.); enddiscreteattrmap; discreteattrvar attrvar=barcolors var=origin attrmap='colors'; layout lattice / columns=2 columnweights=(0 1.0) rowdatarange=union; layout overlay / walldisplay=none yaxisopts=(display=none) xaxisopts=(display=none); scatterplot y=paramn x=param /markercharacterposition=right; endlayout; layout overlay / yaxisopts=(display=(ticks tickvalues) linearopts=(tickvaluesequence=(start=&xmin. end=&xmax. increment=1) tickvalueformat=cateparam.)) xaxisopts=(display=(ticks tickvalues) linearopts=(viewmax=100 viewmin=0 tickvaluesequence=(start=0 end=100 increment=10))); barchart category=paramn response=percent / name='origin' group=barcolors orient=horizontal grouporder=data groupdisplay=stack display=(fill); discretelegend 'origin'; endlayout; endlayout; endgraph; end; run; ods graphics on / reset outputfmt=png imagename='barchart_with_lattice'; proc sgrender data=type_new template=barchart_with_lattice; run;
Did I miss something in 'barchart_with_no_lattice'? Why did not the TickValueFormat work?
Thanks for any information.
The data used by 'PROC SGRENDER' was generated by this code, dataset's name is 'type_new':
data cars; set sashelp.cars; format _all_;informat _all_; run; proc sql noprint; create table type01_01 as select distinct type,origin,count(distinct model) as count from cars group by type,origin; create table type01_02 as select distinct type,count(distinct model) as bign from cars group by type; create table type01 as select lds.*,rds.bign from type01_01 lds left join type01_02 rds on lds.type=rds.type; quit; proc sql noprint; create table type02_01 as select distinct drivetrain,origin,count(distinct model) as count from cars group by drivetrain,origin; create table type02_02 as select distinct drivetrain,count(distinct model) as bign from cars group by drivetrain; create table type02 as select lds.*,rds.bign from type02_01 lds left join type02_02 rds on lds.drivetrain=rds.drivetrain; quit; data type1; length cate param $200 percent 8; set type01(in=a) type02(in=b); if a then cate='1st Category'; else cate='2nd Category'; param=coalescec(type,drivetrain); percent=count/bign*100; run; proc sort;by cate param;run; data type9; set type1; by cate param; output; if first.cate then do; param=strip(cate);call missing(percent,origin); output; end; run; proc sort;by descending cate descending param;run; data type_new; length paramn 8; retain paramn; set type9; by descending cate descending param; if _n_=1 then paramn=0; if first.param then paramn=paramn+1; run;
The format and macro variables was generated by this code:
data format; length fmtname $200 start 8 label type $200; set type_new; fmtname='cateparam'; start=paramn; label=strip(param); type='n'; keep fmtname start label type; run; proc sort data=format nodupkey;by start label;run; proc format library=work cntlin=format;run; proc sql noprint; select min(start) into:xmin trimmed from format; select max(start) into:xmax trimmed from format; quit; %put &xmin. &xmax.; %let color1=vligb; %let color2=liyg; %let color3=lioy;
The full code also was uploaded by 'txt' in the attachment.
@ballardw is correct that the bar chart category axis is discrete by default, causing the TickValueFormat in the LINEAROPTS to be ignored. However, bar chart DO support linear category axes. So, if you set the Y axis explicitly to be TYPE=LINEAR, your format should be honored. Let us know if that works for you.
Learn how use the CAT functions in SAS to join values from multiple variables into a single value.
Find more tutorials on the SAS Users YouTube channel.
Ready to level-up your skills? Choose your own adventure.