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

I created a number of dynamic graphs using sgplot in SAS 9.2 using enterprise guide 5.1.  They all use the group clause.  Is there a way I can assign colors based on the value of the line.

E.g. the group is degree_level values are (degree1 degree2)

Logic is if degree_level =degree1 then make the line blue.

It looks like there is an easy way to do this in 9.3.


The basic code block is:

proc sgplot data=enrollment;       

vline academic_period /response=students_enrolled stat=sum markers group=degree_level;

run; 

1 ACCEPTED SOLUTION

Accepted Solutions
ballardw
Super User

Different variables => different order of values first encountered is a likely cause from my experience.

Prior to 9.3 the only success I had will keeping colors/markers the same from plot to plot was to make sure the order of the desired variables encountered was the same. First value gets the first graphdatacolor options and such through the style.

Sometimes this meant having an order variable indexed to the variable, such as a group variable and presorting the data prior to graphing. Because of this I usually went ahead and pre-summarized the values to plot as well.

View solution in original post

13 REPLIES 13
Jay54
Meteorite | Level 14

Yes, there is an easy way to do this using SAS 9.3 SGPLOT using DiscreteAttrMap. 

However, there is a way you can do this using the INDEX option with SAS 9.2 GTL.  The index=column options tells the plot which graph data element to use for coloring the plot.  a value of 1 means use GraphData1 element.  You can set the index values the way you want in the column, and set the GraphData1-12 elements in the style with the colors you want to get your assignment.

You can use the %MODSTYLE macro to derive a style with the colors you want.  You are not limited to 12 style elements, you can define more if you want.  You may need to summarize your data by the category using PROC MEANS.

ColorByIndex.png

data stocks;

  set sashelp.stocks(where=(date > '01Jan2001'd));

  if stock='IBM' then index=3;

  else if stock='Microsoft' then index=5;

  else index=2;

run;

proc print;run;

proc template;

  define statgraph ColorByIndex;

    begingraph;

      layout overlay;

        seriesplot x=date y=close / group=stock name='a' index=index;

        discretelegend 'a';

      endlayout;

    endgraph;

  end;

run;

proc sgrender data=stocks template=ColorByIndex;

run;

DavidPhillips2
Rhodochrosite | Level 12

Do I have to use sgrender?  Can I use sgplot, which does not have a template function?

Jay54
Meteorite | Level 14

If you have SAS 9.3 or later, you can use SGPLOT with the Discrete Attributes Map feature.  If not, and you want this result, you have to use GTL template with  SGRender since SGPLOT does not expose the INDEX option. 

If you look at the GTL code carefully, the main statements are the SERIESPLOT and DISCRETELEGEND.  These are similar the the SERIES and KEYLEGEND statement in SGPOT.  Rest of the code is boiler plate.

DavidPhillips2
Rhodochrosite | Level 12

This method works however it is incredibly processor inefficient and leads to coding complications.  The idea is to create a second table that will always have data for the given row and link it to the table you are querying.  Is there a better way?

proc sql;

  CREATE TABLE testTable(

        ACADEMIC_PERIOD varchar(50),

        STUDENTS_ENROLLED int,

        STATUS varchar(50),

        DEGREE_LEVEL varchar(50)

   );

  INSERT INTO testTable (Academic_period, STUDENTS_ENROLLED, STATUS, DEGREE_LEVEL)

  VALUES ('1', 10, 'fulltime', 'Bacce');

  INSERT INTO testTable (Academic_period, STUDENTS_ENROLLED, STATUS, DEGREE_LEVEL)

  VALUES ('1', 200, 'fulltime', 'Baccalaureate');

  INSERT INTO testTable (Academic_period, STUDENTS_ENROLLED, STATUS, DEGREE_LEVEL)

  VALUES ('1', 60, 'fulltime', 'Baccalaureate');

  INSERT INTO testTable (Academic_period, STUDENTS_ENROLLED, STATUS, DEGREE_LEVEL)

  VALUES ('2', 20, 'fulltime', 'Baccalaureate');

  INSERT INTO testTable (Academic_period, STUDENTS_ENROLLED, STATUS, DEGREE_LEVEL)

  VALUES ('2', 200, 'fulltime', 'Baccalaureate');

  INSERT INTO testTable (Academic_period, STUDENTS_ENROLLED, STATUS, DEGREE_LEVEL)

  VALUES ('2', 20, 'fulltime', 'Baccalaureate');

  INSERT INTO testTable (Academic_period, STUDENTS_ENROLLED, STATUS, DEGREE_LEVEL)

  VALUES ('1', 20, 'fulltime', 'Doctoral - Research / Scholarship');

  INSERT INTO testTable (Academic_period, STUDENTS_ENROLLED, STATUS, DEGREE_LEVEL)

  VALUES ('2', 20, 'fulltime', 'Doctoral - Research / Scholarship');

  INSERT INTO testTable (Academic_period, STUDENTS_ENROLLED, STATUS, DEGREE_LEVEL)

  VALUES ('1', 20, 'fulltime', 'Doctoral - Research / Scholarship');

  INSERT INTO testTable (Academic_period, STUDENTS_ENROLLED, STATUS, DEGREE_LEVEL)

  VALUES ('1', 20, 'fulltime', 'Doctoral - Research / Scholarship');

  INSERT INTO testTable (Academic_period, STUDENTS_ENROLLED, STATUS, DEGREE_LEVEL)

  VALUES ('1', 20, 'fulltime', 'Doctoral - Research / Scholarship');

  INSERT INTO testTable (Academic_period, STUDENTS_ENROLLED, STATUS, DEGREE_LEVEL)

  VALUES ('1', 20, 'fulltime', 'Doctoral - Research / Scholarship');

  INSERT INTO testTable (Academic_period, STUDENTS_ENROLLED, STATUS, DEGREE_LEVEL)

  VALUES ('1', 20, 'fulltime', 'Doctoral - Research / Scholarship');

quit;

pattern1 color=CX66A5A0 value=l3;      

pattern2 color=CX7C95CA value=solid; 

pattern3 color=CX94BDE1 value=solid;

/*pattern4 color=CXDE7E6F value=solid; 

pattern5 color=CXA9865B value=r3; 

pattern6 color=CXBABC5C value=solid; 

pattern7 color=CXB689CD value=solid; 

pattern8 color=CXCD7BA1 value=solid;*/

/*allow ordering*/

PROC Format;

  Invalue $dLvl

        'Doctoral - Research / Scholarship'='1'

  'Baccalaureate' = '2'

  'Bacce' = '3';

  value $dLvl

  '1'='Doctoral - Research / Scholarship'

        '2'='Baccalaureate'

  '3' ='Bacce';

      

RUN;

                                                                                                                                

data levels_guarantee;

   length degree_level $50;

   Academic_period='1'; degree_level="Doctoral - Research / Scholarship";

   output;

   Academic_period='1'; degree_level="Baccalaureate";

   output;

   Academic_period='1'; degree_level="Bacce";

   output;

   Academic_period='2'; degree_level="Doctoral - Research / Scholarship";

   output;

   Academic_period='2'; degree_level="Baccalaureate";

   output;

   Academic_period='2'; degree_level="Bacce";

   output;

run;

data testTable;

   set testTable levels_guarantee;

run;

%Stpbegin;

title1 ls=1.5 "Test";

axis1 label=none;

axis2 label=none;

axis3 label=none;

proc gchart data=testTable;

  hbar ACADEMIC_PERIOD /

  type=sum

  sumlabel= 'Students Enrolled'

  sumvar=STUDENTS_ENROLLED

  group=Status

  subgroup=degree_level

  discrete

  gaxis=axis1 maxis=axis2 raxis=axis3;

run; Quit;

%Stpend;

DavidPhillips2
Rhodochrosite | Level 12

It looks like sgrender cannot do summations of data like sgplot can with the stat command.  If I were to use sgrender I would have to summarize all of my data on the data layer.

djrisks
Barite | Level 11

David to clarify, do you have SAS 9.2 or SAS 9.3 please?

djrisks
Barite | Level 11

Also you can use the Cartesian join in Proc SQL to generate the second table. Please see example below. And then proc sgplot can be used to plot the data. If you have SAS 9.2 you can assign the colors of the 3 groups more easier by using the %modstyle macro as Sanjay suggested earlier.

proc sql;
  create table automatic_levels_guar as
  select distinct a.ACADEMIC_PERIOD, b.DEGREE_LEVEL
  from testtable as a, testtable as b;
quit;

data automatic_testtable;
  set testtable  automatic_levels_guar;
run;

proc sgplot data = automatic_testtable;
  hbar ACADEMIC_PERIOD / response = STUDENTS_ENROLLED stat = sum group = DEGREE_LEVEL;
  yaxis label = "Full Time";
run;

DavidPhillips2
Rhodochrosite | Level 12

I am using SAS 9.2.

djrisks
Barite | Level 11

Okay. You can use the code above after you create the first testtable dataset to produce the dataset and subsequently the figure that you requested. If you want to assign values to each of the 3 groups you can use the %modstyle macro. Note that the order of the colours that you choose in the modstyle macro are assigned to the alphabetical order of the values in the group.

For more details about how to use the %modstyle macro, see:

SAS/STAT(R) 9.22 User's Guide

or http://www.krissharris.co.uk/SAS%209.2%20Course%20in%20PDF.pdf

DavidPhillips2
Rhodochrosite | Level 12

The process of setting a predefined color scheme is confusing me is there a simple way to do it I’m trying to follow:

http://support.sas.com/documentation/cdl/en/statug/63962/HTML/default/viewer.htm#statug_templt_a0000...

Below is a simple block of what has been discussed so far.

data enrollment3;

set enrollment2;

if student_level='Undergraduate' then index=1;

else if student_level='Graduate' then index=2;

else if student_level='Professional Practice (First professional)' then index=3;

else if student_level='Undergraduate Non-degree Seeking' then index=4;

else if student_level='Graduate Non-degree Seeking' then index=5;

run;

/*block that I’m trying to figure out*/

proc template;

define style Styles.StatColor;

       style GraphData1 / contrastcolor = green;

       style GraphData2 / contrastcolor = purple;

       style GraphData3 / contrastcolor = orange;

end;

define statgraph ColorByIndex;

begingraph;

      layout overlay;          

        seriesplot x=TWO_DIGIT_YEAR y=students_enrolled / group=student_level  name='a' index=index;

      endlayout;

endgraph;

end;

run;

proc sgrender data=enrollment3 template=ColorByIndex;

run;run;

DavidPhillips2
Rhodochrosite | Level 12

I have two series plots that have two separate color schemes.  One is a custom legend series plot the other is a basic series plot.  Any ideas why these two have separate colors?

/*data legend only*/

set enroll_led;

/* For stand alone legend legend */

do i = 6, 10;

xax = i;

output;

end;

drop i;

run;

data legend2;

  set legend;

  if student_level='Undergraduate' then index=1;

  else if student_level='Graduate' then index=2;

  else if student_level='Professional Practice (First professional)' then index=3;

  else if student_level='Undergraduate Non-degree Seeking' then index=4;

  else if student_level='Graduate Non-degree Seeking' then index=5;

run;

proc template;

            define statgraph order;

             dynamic TITLE1 TITLE2;

             begingraph;

             entrytitle TITLE1;

             entrytitle TITLE2;

            layout overlay / xaxisopts =(display = NONE) yaxisopts = (display = NONE)

            y2axisopts = ( display = STANDARD reverse = true label = " ");

            seriesplot x=xax y= student_level / yaxis=y2 group=student_level

            index = index;

            endlayout;

             endgraph;

            end;

run;


Basic plot

data enrollment3;

  set enrollment2;

  if student_level='Undergraduate' then index=1;

  else if student_level='Graduate' then index=2;

  else if student_level='Professional Practice (First professional)' then index=3;

  else if student_level='Undergraduate Non-degree Seeking' then index=4;

  else if student_level='Graduate Non-degree Seeking' then index=5;

proc template;

  define statgraph ColorByIndex;

    begingraph;

      layout overlay;

        seriesplot x=TWO_DIGIT_YEAR y=students_enrolled / group=student_level name='a' index=index;

                        discretelegend 'a';

      endlayout;

    endgraph;

  end;

run;

proc sgrender data=enrollment3 template=ColorByIndex;

run;

ballardw
Super User

Different variables => different order of values first encountered is a likely cause from my experience.

Prior to 9.3 the only success I had will keeping colors/markers the same from plot to plot was to make sure the order of the desired variables encountered was the same. First value gets the first graphdatacolor options and such through the style.

Sometimes this meant having an order variable indexed to the variable, such as a group variable and presorting the data prior to graphing. Because of this I usually went ahead and pre-summarized the values to plot as well.

DavidPhillips2
Rhodochrosite | Level 12

I used a proc print and found that my independent legend had
an extra invisible row.  The extra row throws
the coloring matching off.  Going back to
playing with changing colors.

sas-innovate-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

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.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 13 replies
  • 4777 views
  • 0 likes
  • 4 in conversation