BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
zhangda
Fluorite | Level 6

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;

 

 

1 ACCEPTED SOLUTION

Accepted Solutions
Jay54
Meteorite | Level 14

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;

Goodgraph.png

 

View solution in original post

8 REPLIES 8
Jay54
Meteorite | Level 14

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;

Goodgraph.png

 

zhangda
Fluorite | Level 6

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!

Jay54
Meteorite | Level 14

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/

zhangda
Fluorite | Level 6

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;

Jay54
Meteorite | Level 14

REFTICKS=(label values) 

Rick_SAS
SAS Super FREQ

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.

zhangda
Fluorite | Level 6

Hi Rick,

 

Thank you for your reply, but you know what, to make the curve smooth is the basic requirement from the team leader.

Rick_SAS
SAS Super FREQ

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.

sas-innovate-white.png

Special offer for SAS Communities members

Save $250 on SAS Innovate and get a free advance copy of the new SAS For Dummies book! Use the code "SASforDummies" to register. Don't miss out, May 6-9, in Orlando, Florida.

 

View the full agenda.

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
  • 8 replies
  • 3161 views
  • 1 like
  • 3 in conversation