Hi,
I am oping you are able to help me with below problem. I have a dataset containing 11 variables. have plotted the variables using a stacked bar chart with the date on the x-axis.
Now I want to change the name of the variables in the keylegend box (i.e. Bakk = Bakken (ND & MT), Eagl=Eagle Ford (TX) etc). How can I do this? Below I have pasted my code as well as the figure.
***Import data***;
PROC IMPORT DATAFILE="/folders/myfolders/Speciale/oil/shale oil by basin.xlsx"
OUT=shale_prod
DBMS=XLSX
REPLACE;
***Convert from long to wide format***;
proc sort data=shale_prod out=Wide;
by date;
run;
proc transpose data=Wide
out=Long(rename=(Col1=Value))
name=Source;
by date;
var Eagl Spra Bakk Wolf Bone Niob Miss Aust Wood Rest;
run;
***Assign colors to variables***;
data myattrmap;
length linecolor $ 9 fillcolor $ 9;
input ID $ value $ linecolor $ fillcolor $;
datalines;
myid Eagl VLIGB VLIGB
myid Miss brgr brgr
myid Rest vib vib
myid Spra MOGB MOGB
myid Bakk vigb vigb
myid Bone BLUE BLUE
myid Aust BIGB BIGB
myid Niob PKGR PKGR
myid Wood STOY STOY
myid Wolf PAB PAB
;
***Plot stacked bar chart***;
ods graphics on / width=7in height=4.5in maxlegendarea=60;
proc sgplot data=Long dattrmap=myattrmap;
vbar date / response=Value group=Source groupdisplay=stack grouporder=data attrid=myid;
xaxis type=time thresholdmin=0 max=21100 display=(nolabel);
yaxis grid values=(0 to 7) GRIDATTRS=(color=white) label="Million barrels per day";
keylegend /title="";
run;
data dattrmap;
input id $ value $ fillcolor $;
cards;
id F blue
id M green
;
proc sgplot data=sashelp.class dattrmap=dattrmap;
vbar age/group=sex groupdisplay=stack attrid=id;
legenditem type=FILL name="F" /label='Female' fillattrs=(color=blue);
legenditem type=FILL name="M" /label='Male' fillattrs=(color=green);
keylegend "F" "M";
run;
The easiest and best approach would be to use a format on the source variable as below and then apply that format in sgplot to source variable
proc format ;
value $src
'Bakk'='Bakken (ND & MT)'
'Eagl'='Eagle Ford (TX)';
run;
ods graphics on / width=7in height=4.5in maxlegendarea=60;
proc sgplot data=Long dattrmap=myattrmap;
vbar date / response=Value group=Source groupdisplay=stack grouporder=data attrid=myid;
xaxis type=time thresholdmin=0 max=21100 display=(nolabel);
yaxis grid values=(0 to 7) GRIDATTRS=(color=white) label="Million barrels per day";
keylegend /title="";
format source $src.;
run;
Hi Jag,
Thank you for your reply. While this solves the problem with the key legend, unfortunately this solution disables the custom colouring of the stacked bar chart using the 'myattrmap' code, which is vital for the figure. Is there a way to avoid this?
Alternatively you can try the below code where you derive a new variable source2 and use this variable in place of source
could you please try the let me know if this resolves the issue
proc format ;
value $src
'Bakk'='Bakken (ND & MT)'
'Eagl'='Eagle Ford (TX)';
run;
data Long ;
set Long ;
source2=put(source,$src.);
run;
ods graphics on / width=7in height=4.5in maxlegendarea=60;
proc sgplot data=Long dattrmap=myattrmap;
vbar date / response=Value group=Source2 groupdisplay=stack grouporder=data attrid=myid;
xaxis type=time thresholdmin=0 max=21100 display=(nolabel);
yaxis grid values=(0 to 7) GRIDATTRS=(color=white) label="Million barrels per day";
keylegend /title="";
run;
Hi again Jag,
Unfortunately the issue is the same: I can get a correct legend, but the color mapping disappears. I was though able to resolve the issue based on another solution in this thread. It is a very manual solution, but . nonetheless solved the issue.
But thank you for your help!
@Birgithj wrote:
Hi Jag,
Thank you for your reply. While this solves the problem with the key legend, unfortunately this solution disables the custom colouring of the stacked bar chart using the 'myattrmap' code, which is vital for the figure. Is there a way to avoid this?
Modify the attrmap data set to use the formatted values, or likley better, create a second attribute list with the formatted values but a different attrid. Then you can switch back and forth between behaviors as needed by using format (or not) and the matching attrid. There really isn't much of a limit on how many different attrids can be in the attribute set just follow the rules:
When a discrete attribute map data set contains multiple attribute maps:
The ID variable has more than one value. The VALUE variable has different values that correspond to different data groups. The ID values in the attribute map data set must be continuous (in a sorted order). If they are not, use the SORT procedure to sort the data set by ID, in ascending or descending order.
I have some variables with as many as 6 value sets because sometimes we want longer text, sometimes shorter and sometimes just to have the difference between Show="Attrmap" and Show="Data". There are even times when the same variable is used in mutiple plots that you can use a different attrid for the same variable in the different plots (though legends may get entertaining)
data dattrmap;
input id $ value $ fillcolor $;
cards;
id F blue
id M green
;
proc sgplot data=sashelp.class dattrmap=dattrmap;
vbar age/group=sex groupdisplay=stack attrid=id;
legenditem type=FILL name="F" /label='Female' fillattrs=(color=blue);
legenditem type=FILL name="M" /label='Male' fillattrs=(color=green);
keylegend "F" "M";
run;
SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!
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.