BookmarkSubscribeRSS Feed
Anita_n
Pyrite | Level 9

Dear all,

I created a graph using sgpanel but since my legend is too large, it compresses the graph which doesn't make it look nice. On searching through the internet I came accross this article which says Microsoft Word - More to it than Meets the Eye.doc (lexjansen.com)

a Legend can be created seperate from the graph using an annotate facility. I have being tring to follow up the description but am not really getting it.

Could someone maybe help?

 

I used sashelp.cars here as test data. Here is my code:

I tried to transform sashelp.cars data to look like my data:

data have;
length make_combi $50;
set sashelp.cars;
if _n_ <= 20 then do; make_combi="Accura"; end;
if _n_ >= 21 and _n_<=40 then do; make_combi= "Dodge+Buick+Ford" ; end;      
if _n_ >= 41 and _n_<=60 then do; make_combi= "Dodge+Buick+GMC"; end;       
if _n_ >= 61 and _n_<=75 then do; make_combi="Accura+Audi+BMW"; end;

if _n_ >= 76 and _n_<=90 then do; make_combi="Accura+Buick"; end;
if _n_ >= 91 and _n_<=100 then do; make_combi= "Chevrolet"; end;                               
if _n_ >= 101 and _n_<=120 then do; make_combi= "Honda"; end;                                    

if _n_ >= 121 and _n_<=160 then do; make_combi="Accura+Buick+BMW"; end;
if _n_ >= 161 and _n_<=170 then do; make_combi= "Hummer"; end;                           
if _n_ >=171 and _n_<=180 then do; make_combi= "Hummer+Buick" ; end;                
if _n_ >= 181 and _n_<=190 then do; make_combi= "Hummer+Buick+BMW"; end;   
if _n_ >= 191 and _n_<=200 then do; make_combi= "Hummer+Buick+Hyundai"; end; 

if _n_ >= 201 and _n_<=210 then do; make_combi="Accura+Buick+Chevrolet"; end;
if _n_ >= 211 and _n_<=220 then do; make_combi="Cadillac"; end;
if _n_ >= 221 and _n_<=230 then do; make_combi="Chrysler"; end;
if _n_ >= 231 and _n_<=240 then do; make_combi="Chrysler+Audi"; end;

if _n_ >= 281 and _n_<=290 then do; make_combi= "Chrysler+Buick" ; end;

if _n_ >= 291 and _n_<=300 then do; make_combi= "Jaguar"; end;                               
if _n_ >= 301 and _n_<=310 then do; make_combi="Chrysler+Buick+BMW"; end; 

if _n_ >= 311 and _n_<=320 then do; make_combi= "Jaguar+BMW"; end;                 
if _n_ >= 321 and _n_<=330 then do; make_combi="BMW"; end;
if _n_ >= 231 and _n_<=340 then do; make_combi= "Jaguar+Hyundai"; end;       
 
if _n_ >= 341 and _n_<=360 then do; make_combi="Dodge" ; end; 
if _n_ >= 361 and _n_<=380 then do; make_combi= "Dodge+Buick+BMW" ; end;     
 
if _n_ >= 381 and _n_<=390 then do; make_combi="Dodge+Chevrolet" ; end; 
if _n_ >= 391 and _n_<=400 then do; make_combi= "Jaguar+Audi"; end;                 
 
if _n_ >=401 and _n_<=420 then do; make_combi= "Dodge+Audi"; end;                
if _n_ >= 421 and _n_<=440 then do; make_combi= "Dodge+Buick" ; end;  
 
       

keep make type make_combi;
run;

I then created the format using proc format as described in the paper

proc format; 
value BarLabel 1="Accura"                              
2= "Accura+Audi+BMW"  
3= "Accura+Buick"                   
4= "Accura+Buick+BMW"      
5= "Accura+Buick+Chevrolet"         
6= "Cadillac"                
7= "Chrysler"               
8= "Chrysler+Audi"                        
9= "Chrysler+Buick"                            
10= "Chrysler+Buick+BMW"              
11= "BMW"                            
12= "Dodge"                              
13= "Dodge+Chevrolet"                   
14= "Dodge+Audi"                
15= "Dodge+Buick"                    
16= "Dodge+Buick+BMW"      
17= "Dodge+Buick+Ford"       
18= "Dodge+Buick+GMC"       
19= "Chevrolet"                               
20= "Honda"                                    
21= "Hummer"                           
22= "Hummer+Buick"                 
23= "Hummer+Buick+BMW"   
24= "Hummer+Buick+Hyundai" 
25= "Ford"                             
26= "Infiniti"                      
27= "Hyundai"                          
28= "Audi"                            
29= "Audi+Hyundai"            
30= "Jaguar"                               
31= "Jaguar+BMW"                 
32= "Jaguar+Hyundai"               
33= "Jaguar+Audi"                 
34= "Jaguar+Audi+Hyundai" 
35= "Jaguar+Buick"                     
36= "Jaguar+Buick+BMW"       
37= "Jaguar+Buick+Chevrolet"          
38= "MINI"                               
39= "Buick"                                
40= "Buick+BMW"                 
41= "Buick+Chevrolet"                     
42= "Buick+Ford"                   
43= "Buick+Hyundai"                
44= "Buick+GMC"                   
45= "GMC"                             
;

value BarColor 1= "CX00FA9A"
2= "CX0000FF"
3= "CXFFE4C4"
4= "CX696969"
5= "CX8B0000"
6= "CX5F9EA0"
7= "CXB8860B"
8= "CX8FBC8F"
9= "CX1E90FF"
10= "CXADFF2F"
11= "CXFFEBCD"
12= "CXF08080"
13= "CX00CED1"
14= "CXFFDAB9"
15= "CXB22222"
16= "CX00FFFF"
17= "CXFF8C00"
18= "CXE0FFFF"
19= "CX4682B4"
20= "CXE0FFFF"
21= "CX40E0D0"
22= "CX008080"
23= "CX8B4513"
24= "CX4169E1"
25= "CXBC8F8F"
26= "CX696969"
27= "CXD2691E"
28= "CX7FFF00"
29= "CXBDB76B"
30= "CXE9967A"
31= "CX483D8B"
32= "CXDCDCDC"
33= "CX2F2F2F"
34= "CXFFF0F5"
35= "CXFF0000"
36= "CX808000"
37= "CXFFDEAD"
38= "CX7B68EE"
39= "CX0000CD"
40= "CX20B2AA"
41= "CXADFF2F"
42= "CXFFD700"
43= "CXFF1493"
44= "CX8B008B"
45= "CX8FBC8F"
;

run;

Here is the code for the annotate data, the %cbar is not working (so the colors are also not showing) that is why I commented it out, Or maybe am doing something wrong. Or there is a better way to do that

data want;
set have;

do i=1 to max(_n_);
   BarLabel= put(i, BarLabel.);
   BarColor= put(i, BarColor.);
   %annomac;
   %bar(4,44-(i*3),8,42-(i*3),black, 0, e);
   *%cbar(4,44-(i*3), 8,42-(i*3), BarColor,3,s);
   %label(10,43.3-(i*3), BarLabel, black, 0,0,0.5,'Arial',6);
end;
run;

to create the legend using 

 

filename legend "mypath\test2.gif";
goptions device=gif gsfname=legend hsize=5in vsize=12in;

proc gslide anno=want;
run;
quit;

Thanks for any help

5 REPLIES 5
ballardw
Super User

You may need to explain what you think

do i=1 to max(_n_)

does in that data step.

Your first data step code shows that you are aware that _n_ could be as large as 440 and your have set would have that many records. So for any _n_ > then 45 you have more calls to the formats than you have defined. Unless you did some thing to the HAVE data set before that want.

First thing when using helper macros like %annomac, they should be called before any data step or procedure that want to use the result. There are timing issues related.

Second, for a legend, which typically has a fixed number of elements, you likely do not need the use the HAVE data set at all as you only want the 45 elements you have defined.

 

An obnoxious result from your internet search is is that you are using the older SAS/Graph annotate macros, %annomac which do not align with the newer SGPLOT/SGPanel and related graphics programs. There significant differences in what the macros do and how they address space. That paper appears to be about 14 years old.

You might look into %sganno and use the sg annotate macros instead.

 

Suggestion: since your example uses the SAS supplied Sashelp.cars, thank you for providing a set, provide your current SGPANEL code using that same set. Likely the option NOAUTOLEGEND will figure into a solution to create the graph without the legend and then add one.

Anita_n
Pyrite | Level 9

@ballardw thanks for the comments . Here is the code for my sgpanel plot. I wish to seperate the legend from the plot and probably use ods gridded layout to place these side by side

 

data have;                                          
infile datalines;                                   
input make_combi	$20. period	 $14.    status	amount;
                                                    
datalines;                                      
Accura				  before 2005    1	    1       
Accura+Buick	      2005 to 2015	 1	    7       
Accura+Buick	      before 2005    1	    10      
Accura+Buick	      since 2015     1	    11      
Accura+Buick+Audi     2005 to 2015	 1	    1       
Chrysler+BMW		  since 2015     1	    1       
Dodge+Buick			  2005 to 2015	 1	    13      
Dodge+Buick			  before 2005    1	    28      
Dodge+Buick			  since 2015     1	    21      
Honda 	              before 2005    1	    3       
Honda 	              since 2015     1	    1       
Honda+Buick			  2005 to 2015	 1	    49      
Honda+Buick			  before 2005	 1      29      
Honda+Buick			  since 2015     1	    50      
Honda+Buick+Audi	  2005 to 2015	 1	    14      
Honda+Buick+Audi	  before 2005    1	    1       
Honda+Buick+Audi	  since 2015     1	    9       
Hyundai	              2005 to 2015	 1	    1       
Hyundai	              before 2005    1	    4       
Hyundai+BMW+Ford	  2005 to 2015	 1	    1       
Hyundai+Buick		  2005 to 2015	 1	    8       
Hyundai+Buick		  before 2005    1	    15      
Hyundai+Buick		  since 2015     1	    13      
Hyundai+Buick+Audi	  2005 to 2015	 1	    2       
Hyundai+Buick+Audi	  before 2005    1	    1       
Hyundai+Buick+Audi	  since 2015     1	    2       
Hyundai+Buick+MINI	  before 2005    1	    1       
Hyundai+Buick+MINI	  since 2015     1	    6       
Buick				  2005 to 2015	 1	    3       
Buick				  before 2005    1	    2       
Buick				  since 2015     1	    2       
Buick+MINI	          since 2015     1	    1       
Accura+Buick		  before 2005    2	    13      
Accura+Buick		  since 2015     2      1       
Accura+Buick+MINI	  before 2005    2	    1       
Chrysler+Buick		  2005 to 2015	 2	    3       
Chrysler+Buick		  since 2015     2	    1       
Chrysler+Buick+Audi   since 2015     2	    1       
Audi	              2005 to 2015	 2	    10      
Audi	              before 2005    2	    5       
Audi	              since 2015     2	    21      
Dodge+MINI	          before 2005    2	    1       
Dodge+BMW		  	  2005 to 2015	 2	    1       
Dodge+Buick			  2005 to 2015	 2	    7       
Dodge+Buick			  before 2005    2	    26      
Dodge+Buick			  since 2015     2	    1       
Dodge+Buick+Audi	  2005 to 2015	 2	    1       
Dodge+Buick+Infiniti  2005 to 2015	 2	    2       
Dodge+Buick+Infiniti  before 2005    2	    7       
Honda 	              before 2005    2	    1       
Honda+Buick			  2005 to 2015	 2	    3       
Honda+Buick			  before 2005    2	    11      
Honda+Buick			  since 2015     2	    2       
Honda+Buick+Audi	  2005 to 2015	 2	    1       
BMW		  	          before 2005    2	    1       
Hyundai	              before 2005    2	    2       
Hyundai	              since 2015     2	    1       
Hyundai+Audi	      since 2015     2	    3       
Hyundai+Buick		  2005 to 2015	 2	    3       
Hyundai+Buick		  before 2005    2	    9       
Hyundai+Buick		  since 2015     2	    2       
Hyundai+Buick+Audi	  2005 to 2015	 2	    1       
Hyundai+Buick+MINI	  2005 to 2015	 2	    1       
Hyundai+Buick+MINI	  since 2015     2	    1       
Ford	              2005 to 2015	 2	    2       
Buick				  before 2005    2	    3       
Buick				  since 2015     2	    1       
Buick+Audi	          since 2015     2	    5       
Buick+GMC	          2005 to 2015	 2	    1       
Buick+Ford	          since 2015     2	    1       
Infiniti	          2005 to 2015	 2	    1       
Infiniti	          before 2005    2	    5       
Accura				  before 2005    3	    1       
Accura+BMW+Audi	      since 2015     3	    1       
Accura+Buick		  before 2005    3	    2       
Accura+Buick		  since 2015     3	    1       
Chrysler+BMW		  before 2005    3	    1       
Chrysler+Buick		  2005 to 2015	 3	    3       
Chrysler+Buick		  since 2015     3	    2       
Audi	              2005 to 2015	 3	    7       
Audi	              before 2005    3	    7       
Audi	              since 2015     3	    6       
Dodge+BMW		  	  before 2005    3	    1       
Dodge+Buick			  2005 to 2015	 3	    2       
Dodge+Buick			  before 2005    3	    9       
Dodge+Buick			  since 2015     3	    5       
Dodge+Buick+Infiniti  2005 to 2015	 3	    1       
Dodge+Buick+Infiniti  before 2005    3	    2       
Dodge+Buick+Infiniti  since 2015     3	    1       
MINI	              before 2005    3   	1     
MINI	              since 2015     3	    1       
Honda+Buick			  2005 to 2015	 3	    1       
Honda+Buick			  before 2005    3	    2       
Honda+Buick			  since 2015     3	    1       
GMC	                  since 2015     3	    2       
BMW		  	          since 2015     3	    1       
BMW+Ford	          2005 to 2015	 3	    1       
Hyundai	              before 2005    3	    2       
Hyundai	              since 2015     3	    1       
Hyundai+Ford	      since 2015     3	    1       
Hyundai+Buick		  2005 to 2015	 3	    2       
Hyundai+Buick		  before 2005    3	    3       
Hyundai+Buick		  since 2015     3	    5       
Hyundai+Buick+MINI	  before 2005    3	    1       
Ford	              2005 to 2015	 3	    1       
Ford	              before 2005    3	    1       
Buick				  before 2005    3	    3       
Buick+GMC	          2005 to 2015	 3	    1       
Buick+GMC	          since 2015     3	    1       
Infiniti	          before 2005    3	    6       
Accura+Buick		  before 2005    4	    5       
Accura+Buick+MINI	  before 2005    4	    1       
Audi	              2005 to 2015	 4	    7       
Audi	              before 2005    4	    5       
Audi	              since 2015     4	    3       
Dodge+Buick			  before 2005    4	    7       
Dodge+Buick			  since 2015     4	    1       
Dodge+Buick+GMC	      before 2005    4	    1       
Dodge+Buick+Infiniti  before 2005    4	    2       
GMC	                  2005 to 2015	 4	    1       
GMC	                  since 2015     4	    1       
Hyundai	              before 2005    4	    1       
Hyundai	              since 2015     4	    2       
Hyundai+Audi	      before 2005    4	    1       
Hyundai+BMW		  	  2005 to 2015	 4	    1       
Hyundai+Buick		  2005 to 2015	 4	    2       
Hyundai+Buick		  before 2005    4	    1       
Hyundai+Buick		  since 2015     4	    1       
Hyundai+Buick+MINI	  before 2005    4	    1       
Hyundai+Buick+MINI	  since 2015     4	    1       
Ford	              before 2005    4	    1       
Ford	              since 2015     4	    2       
Buick				  before 2005    4	    2       
Buick+Audi	          2005 to 2015	 4	    1       
Buick+Audi	          since 2015     4	    1       
Buick+GMC	          2005 to 2015	 4	    1       
Accura+Buick		  since 2015     5	    2       
Chrysler+Buick		  before 2005    5	    1       
Chrysler+Buick		  since 2015     5	    1       
Audi	              before 2005    5	    1       
Dodge+Buick+Infiniti  before 2005    5	    2       
Honda +Buick+Ford	  2005 to 2015	 5	    1       
Hyundai+Audi	      2005 to 2015	 5	    2       
Hyundai+Buick		  before 2005    5	    3       
Hyundai+Buick		  since 2015     5	    1       
Hyundai+Buick+MINI	  since 2015     5	    1       
Ford	              2005 to 2015	 5	    1       
Ford	              since 2015     5	    2       
Buick				  2005 to 2015	 5	    1       
Buick+GMC	          2005 to 2015	 5	    1       
Buick+GMC	          since 2015     5	    2       
Buick+Infiniti	      2005 to 2015	 5	    1       
Audi	              before 2005    6	    1       
GMC	                  before 2005    6	    1       
Hyundai	              since 2015     6	    1       
Hyundai+Buick		  before 2005    6	    1       
Ford	              before 2005    6	    1       
Buick				  2005 to 2015	 6	    1       
Buick				  before 2005    6	    1       
Buick+Audi	          before 2005    6	    1       
Buick+MINI	          2005 to 2015	 6	    1       
Buick+MINI	          before 2005    6	    1       
Buick+GMC	          before 2005    6	    1       
Buick+GMC	          since 2015     6	    1       
Buick+Ford	          since 2015     6	    1       
Audi	              before 2005    7	    1       
Dodge	  	          before 2005    7	    1       
Hyundai+Buick		  before 2005    7	    1       
Ford	              2005 to 2015	 7	    1       
Infiniti	          since 2015     7	    1       
Hyundai+Buick+MINI	  2005 to 2015	 8	    1       
Ford	              2005 to 2015	 9	    1       
;                                                   
run;                                                
                                                    
                                                    
ods graphics / maxlegendarea=100 width=4in height=3in;                                                   
proc sgpanel data=have pad=(bottom=5%) noautolegend;

panelby  period/ columns=3 novarname noborder headerattrs=(color=black family="arial" weight=bold size=7pt) 
nowall sort=data;

vbar status /response=amount group=make_combi  groupdisplay=stack attrid=make_combi missing; 

rowaxis grid display=(nolabel) valueattrs=(size=5pt family="arial" color=black) 
grid minor ;

colaxis  display=(nolabel) discreteorder=unformatted  valueattrs=(size=5pt family=arial color=dimgray) valuesrotate=diagonal2 
;


keylegend / position=bottom  title="" valueattrs=(size=4pt family=arial) outerpad=(top=0.2cm) sortorder=ascending noborder;
run;
                                                   

 

Or if there is a better alternative, I will be grateful

ballardw
Super User

Before going on I am going to make a style suggestion that may help down the road. Instead of creating text values like "before 2005" "2005 to 2015" and "since 2015" that you use a NUMERIC variable and custom format to display the desired text.

The groups created by a custom format will allow things to sort properly in general. So if you had something like

Proc Format;
value yeargroup
2000- 2004 = 'before 2005'
2005-2015  = '2005 to 2015'
2016-2025  = 'since 2015'
;
run;

then with a variable holding the actual year you have some flexibility. For instance a different format with the same data set could great groups/graphs of different periods.

Second relates to Input statements using fixed column syntax and data that contains tabs. You may not realize that what you created below has tab characters between the columns. Which means that when others copy the code and paste into an editor that their tab settings may mean that the code won't run properly, especially when you use a FIXED format, i.e Period $14. to read it. My version of your data set has 16 values for Period as the fixed columns cut off many values at the front and then include some of the values of status, leaving amount missing.

A second advantage of reading your Period as a single year would be not having to do anything to read in the spaces between words, which is why I assume you used a fixed column input.

Anita_n
Pyrite | Level 9

@ballardw okay, thanks for that suggestion

Anita_n
Pyrite | Level 9

Is there really a solution to this problem?

SAS Innovate 2025: Register Now

Registration is now open for SAS Innovate 2025 , our biggest and most exciting global event of the year! Join us in Orlando, FL, May 6-9.
Sign up by Dec. 31 to get the 2024 rate of just $495.
Register now!

How to Concatenate Values

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.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 5 replies
  • 667 views
  • 0 likes
  • 2 in conversation