Hello,
I have a code below where a two-curve outlay on a red/blue bar chart. But I have two questions to ask. First, how to add new colors such as orange/purple on the two curves so that the curves could distinguish themselves from bar charts, which could also make the d_2015, d_2016 rows corresponding the curves under the graph distinguish those of bar chart. Second, is it possible to add gridded line on the fours d_2015, d_2016 rows and the row of 'Null, S_300, S_640,S_670....." Thank you so much!
data ds1;
input year $ mid $ resp1 resp2;
datalines;
null d_2016 0.45 0.64
null d_2015 0.35 0.783
s_300 d_2016 0.65 0.67
s_300 d_2015 0.55 0.75
s_640 d_2016 0.42 0.89
s_640 d_2015 0.65 0.87
s_670 d_2016 0.35 0.12
s_670 d_2015 0.75 0.09
s_700 d_2016 0.83 0.06
s_700 d_2015 0.47 0.07
s_730 d_2016 0.48 0.18
s_730 d_2015 0.58 0.21
s_760 d_2016 0.67 0.05
s_760 d_2015 0.69 0.045
;
run;
ods graphics / reset attrpriority=color width=5in height=3in imagename='Goodgraph';
title 'Score Distribution';
proc sgplot data=ds1 noborder noautolegend;
vbarparm category=year response=resp1 / group=mid groupdisplay=cluster
outlineattrs=(color=black) barwidth=0.8;
xaxistable resp1 / class=mid colorgroup=mid;
xaxis display=(nolabel);
yaxis display=(nolabel);
series x=year y=resp2 / group=mid smoothconnect
lineattrs=(thickness=2);
xaxistable resp2 / class=mid colorgroup=mid; styleattrs datacontrastcolors=(red blue);
xaxis display=(nolabel) label="Year";
yaxis label="Rate" tickvalueformat= percent7.0;
run;
What you want is a bit more complex, but can be done using the Discrete Attributes Map. This is like a format, but for line and bar colors. You need two group columns, one for each response, and unique values for the groups. I generated these by adding a "_2" to the other ones. I used this way. Alternatively, it may be preferable to have one response column, with 4 unique group values in "Mid". You also need to define a DATTRMAP data set, setting the colors for each group value.
data ds1; input year $ mid $ resp1 resp2; mid2=cat(strip(mid), "_2"); datalines; null d_2016 0.45 0.64 null d_2015 0.35 0.783 s_300 d_2016 0.65 0.67 s_300 d_2015 0.55 0.75 s_640 d_2016 0.42 0.89 s_640 d_2015 0.65 0.87 s_670 d_2016 0.35 0.12 s_670 d_2015 0.75 0.09 s_700 d_2016 0.83 0.06 s_700 d_2015 0.47 0.07 s_730 d_2016 0.48 0.18 s_730 d_2015 0.58 0.21 s_760 d_2016 0.67 0.05 s_760 d_2015 0.69 0.045 ; /*--Define Attr Map for groups--*/ data attrmap; length value FillColor LineColor TextColor $12; Id='X'; Value="d_2015"; FillStyleElement='graphdata1'; LineStyleElement='graphdata1'; TextStyleElement='graphdata1';output; Id='X'; Value="d_2016"; FillStyleElement='graphdata2'; LineStyleElement='graphdata2'; TextStyleElement='graphdata2';output; Id='X'; Value="d_2015_2"; FillStyleElement='graphdata3'; LineStyleElement='graphdata3'; TextStyleElement='graphdata3';output; Id='X'; Value="d_2016_2"; FillStyleElement='graphdata4'; LineStyleElement='graphdata4'; TextStyleElement='graphdata4';output; run; ods listing gpath='.' image_dpi=200; ods graphics / reset attrpriority=color width=5in height=3in imagename='Goodgraph'; title 'Score Distribution'; proc sgplot data=ds1 noborder noautolegend cycleattrs dattrmap=attrmap; vbarparm category=year response=resp1 / group=mid groupdisplay=cluster outlineattrs=(color=black) barwidth=0.8 attrid=X; series x=year y=resp2 / group=mid2 smoothconnect attrid=X lineattrs=(thickness=3); xaxistable resp1 / class=mid colorgroup=mid attrid=X; xaxistable resp2 / class=mid2 colorgroup=mid2 attrid=X; xaxis display=(nolabel) label="Year"; yaxis offsetmin=0 label="Rate" tickvalueformat= percent7.0; run;
What you want is a bit more complex, but can be done using the Discrete Attributes Map. This is like a format, but for line and bar colors. You need two group columns, one for each response, and unique values for the groups. I generated these by adding a "_2" to the other ones. I used this way. Alternatively, it may be preferable to have one response column, with 4 unique group values in "Mid". You also need to define a DATTRMAP data set, setting the colors for each group value.
data ds1; input year $ mid $ resp1 resp2; mid2=cat(strip(mid), "_2"); datalines; null d_2016 0.45 0.64 null d_2015 0.35 0.783 s_300 d_2016 0.65 0.67 s_300 d_2015 0.55 0.75 s_640 d_2016 0.42 0.89 s_640 d_2015 0.65 0.87 s_670 d_2016 0.35 0.12 s_670 d_2015 0.75 0.09 s_700 d_2016 0.83 0.06 s_700 d_2015 0.47 0.07 s_730 d_2016 0.48 0.18 s_730 d_2015 0.58 0.21 s_760 d_2016 0.67 0.05 s_760 d_2015 0.69 0.045 ; /*--Define Attr Map for groups--*/ data attrmap; length value FillColor LineColor TextColor $12; Id='X'; Value="d_2015"; FillStyleElement='graphdata1'; LineStyleElement='graphdata1'; TextStyleElement='graphdata1';output; Id='X'; Value="d_2016"; FillStyleElement='graphdata2'; LineStyleElement='graphdata2'; TextStyleElement='graphdata2';output; Id='X'; Value="d_2015_2"; FillStyleElement='graphdata3'; LineStyleElement='graphdata3'; TextStyleElement='graphdata3';output; Id='X'; Value="d_2016_2"; FillStyleElement='graphdata4'; LineStyleElement='graphdata4'; TextStyleElement='graphdata4';output; run; ods listing gpath='.' image_dpi=200; ods graphics / reset attrpriority=color width=5in height=3in imagename='Goodgraph'; title 'Score Distribution'; proc sgplot data=ds1 noborder noautolegend cycleattrs dattrmap=attrmap; vbarparm category=year response=resp1 / group=mid groupdisplay=cluster outlineattrs=(color=black) barwidth=0.8 attrid=X; series x=year y=resp2 / group=mid2 smoothconnect attrid=X lineattrs=(thickness=3); xaxistable resp1 / class=mid colorgroup=mid attrid=X; xaxistable resp2 / class=mid2 colorgroup=mid2 attrid=X; xaxis display=(nolabel) label="Year"; yaxis offsetmin=0 label="Rate" tickvalueformat= percent7.0; run;
Hi Sanjay,
Is it possible that another parallel vertical line is added to the right side of the graph below, where 0%,20%,40%,60%,80% are labelled respectively as the vertical line on the left side the graph showed. Thanks!
Yes. You can use the REFTICKS option to repeat the same axis on the other side.
Or, you can display a 2nd independent axis (Y2) by setting some plots to Y2AXIS.
http://blogs.sas.com/content/graphicallyspeaking/2016/07/24/stock-plots/
Hi Sanjay,
Thank you so much for your guidance, but I still have a couple of questions.
1. How can I put the vertical axis the percentage data ranging from 0% to 100% instead of '0% to 80%'?
2. I added reftick option as the code below, but why there is no '0% ,20%, 40%, 60%, 80%', just a naked parallel vertical axis.
3. I also added a label beside it as ' Second rate', as the axis on the left side shows , but why the ' Second rate' does not show off ?
4. I remove the noautolegend option, but why I can only have two small blocks showing 2 colors, for which I am supposed to have four blocks showing 4 colors instead,
5. Apart from color reminder, can I add a piece of block and a piece of line also, to remind readers that what color and what shape represents what color?
6. How can I move the legend showing 4 colors and 4 shapes down and put it ahead of 'd_2015','d_2015','d_2015_2', 'd_2016_2' respectively so that the readers can figure out what color adn what shape represents what data at first sight.
Thank you so much!
data ds1;
input year $ mid $ resp1 resp2;
mid2=cat(strip(mid), "_2");
datalines;
null d_2016 0.45 0.64
null d_2015 0.35 0.783
s_300 d_2016 0.65 0.67
s_300 d_2015 0.55 0.75
s_640 d_2016 0.42 0.89
s_640 d_2015 0.65 0.87
s_670 d_2016 0.35 0.12
s_670 d_2015 0.75 0.09
s_700 d_2016 0.83 0.06
s_700 d_2015 0.47 0.07
s_730 d_2016 0.48 0.18
s_730 d_2015 0.58 0.21
s_760 d_2016 0.67 0.05
s_760 d_2015 0.69 0.045
; run;
data attrmap;
length value FillColor LineColor TextColor $12;
Id='X'; Value="d_2015"; FillStyleElement='graphdata1'; LineStyleElement='graphdata1'; TextStyleElement='graphdata1';output;
Id='X'; Value="d_2016"; FillStyleElement='graphdata2'; LineStyleElement='graphdata2'; TextStyleElement='graphdata2';output;
Id='X'; Value="d_2015_2"; FillStyleElement='graphdata3'; LineStyleElement='graphdata3'; TextStyleElement='graphdata3';output;
Id='X'; Value="d_2016_2"; FillStyleElement='graphdata4'; LineStyleElement='graphdata4'; TextStyleElement='graphdata4';output;
run;
ods listing gpath='.' image_dpi=200;
ods graphics / reset attrpriority=color width=5in height=3in imagename='Goodgraph';
title 'Score Distribution';
proc sgplot data=ds1 noborder cycleattrs dattrmap=attrmap;
vbarparm category=year response=resp1 / group=mid groupdisplay=cluster
outlineattrs=(color=black) barwidth=0.8 attrid=X;
series x=year y=resp2 / group=mid2 smoothconnect attrid=X
lineattrs=(thickness=3);
xaxistable resp1 / class=mid colorgroup=mid attrid=X;
xaxistable resp2 / class=mid2 colorgroup=mid2 attrid=X;
xaxis display=(nolabel) label="Year";
yaxis offsetmin=0 label="Rate" tickvalueformat= percent7.0
REFTICKS label="Second Rate" tickvalueformat= percent7.0;
run;
REFTICKS=(label values)
IMHO, you should get rid of the SMOOTHCONNECT option. The X axis is categorical, so a smooth curve is misleading and doesn't make sense.
Hi Rick,
Thank you for your reply, but you know what, to make the curve smooth is the basic requirement from the team leader.
Does the X axis represent time values such as 0, 300, 640,... days? If so, then a smooth curve would make sense. However, if the axis represents time points then you should space out the axis in a linear fashion, so that the distance betwee 300 and 640 is not the same as the distance between 640 and 670.
Build your skills. Make connections. Enjoy creative freedom. Maybe change the world. Registration is now open through August 30th. Visit the SAS Hackathon homepage.
Register today!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.
Select SAS Training centers are offering in-person courses. View upcoming courses for: