BookmarkSubscribeRSS Feed
☑ This topic is solved. Need further help from the community? Please sign in and ask a new question.
BAGaucho
Obsidian | Level 7

Hi,

 

I just had a request a Waterfall plot from my internal client that he wants to use solid colors for the first five groups but 2 groups with color and pattern. I tried to use Discrete Attribute Map data but I don't think fillpattern variable is available although I am not getting any SAS error message. If fillpattern works in the data, that will be great.

 

Then, I tried styleattrs statement with datafillpatterns option. The main problem is that there is no option "not to put any pattern". For the good old SAS/Graph, pattern statement had two options as 'E' and 'S' but the 15 values for datafillpatterns do not include any null value.

 

I tried datafillpatterns=('  '   '  '  '  ' X1 X1 R1 L1) but I got syntax error. Is there any way to indicate "blank" value to datafillpatterns option?  I know one more method would be proc template but I haven't tried yet.

 

Any idea? Thank you in advance.

 

Raymond

1 ACCEPTED SOLUTION

Accepted Solutions
BAGaucho
Obsidian | Level 7

I am leaving this for anyone who may need it in the future...

 

With ballardw's suggestion, I tried many different combinations of codes. Finally, I came up with what I needed using two vbarparm statements but not that simple as I expected. If SAS company add S and E options to datafillpatterns in styleattrs statement or fillpattern variable in ATTRMAP data, it would be super easy task.

 

This is what I ended up doing...

1. For the first vbarparm, I listed all groups with proper colors I want (using either ATTRMAP or styleattrs)

2. For the second vbarparm, I had to trick the data. Need to create a trt2 variable and I made the response variable (my case is cfb but created a temp variable as cfb2) value to be zero so it will not overwrite other groups (solid color group).  I still need to specify fillpattern fillpatternattrs=(pattern=r1) nofill options to put pattern to second groups. Still I cannot use multiple patterns but only one since I can only specify one pattern for fillpatternattrs option.

3. I cannot use Keylegend statement anymore so I have to create multiple legenditem statements per individual group

 

Yes, I managed to create a bar plot with both solid color with and without pattern, but this should be super easy if we have one extra option. I hope SAS can add this option someday.  

 

Cheers!

View solution in original post

11 REPLIES 11
ballardw
Super User

I am not sure what you are attempting when you say "not to put any pattern". Do you mean a solid fill? or nothing at all (no color)?

 

You might provide example data, the current plot attempts you have made, entire sgplot/sgpanel/GTL and Sgrender, the dattrmap data set and what the description of the result you are looking for.

 

 

And example of different color and fill patterns with a bar chart modified from https://support.sas.com/kb/43/770.html

Note that the S fill pattern overrides the dataskin while E uses the skin but no pattern.

This example uses a data set you should have available so just copy/paste and run the code.

proc template;
   define statgraph regress;
   begingraph;
      entrytitle 'A Variety of Fill Patterns';
      layout overlay;
         barchart x=name y=height / group=name display=(fillpattern fill outline) dataskin=sheen;
      endlayout;
   endgraph;
   end;

/* Fill patterns are defined using the FILLPATTERN style element attribute. */
   define style styles.mypatterns;
   parent=styles.listing;
      style GraphData1 from GraphData1 /                                      
            fillpattern = "S";                                                  
      style GraphData2 from GraphData2 /
            fillpattern = "E";                                                  
      style GraphData3 from GraphData3 /                                      
            fillpattern = "R1";                                                  
      style GraphData4 from GraphData4 /                                      
            fillpattern = "L5";                                                  
      style GraphData5 from GraphData5 /                                      
            fillpattern = "X5";                                                  
      style GraphData6 from GraphData6 /                                      
            fillpattern = "R5";                                                  
    end;
run;

data class;
   set sashelp.class;
   if _n_ < 7;
run;

ods html style=mypatterns;
ods graphics / reset border width=600px height=400px;

proc sgrender data=class template=regress;
run;

 

 

BAGaucho
Obsidian | Level 7

Thanks for such a quick response. Sorry about vague description. Yes, 5 groups for solid color without any pattern and two new groups with colors with pattern. That's what I need to do.

 

I saw the proc template example before I posted but didn't noticed I can use fillpattern='S'. If we can use fillpattern='S', I wonder why I can't use datafillpatterns=(S S S S S X1 L1)? It seems that SGPlot removed the pattern options S & E. 

 

Also, for a test, I tried apply all groups to X1 pattern but no impact without any SAS error.

data attrmap;

  set amap;

 ...

  fillepattern='X1';

run;

I wonder whether I can use fillpattern statement in Discrete Attribute Map data. I love to use Discrete Attribute Map data for all my SG procedures and I wish fillpattern='S' works.

ballardw
Super User
Spoiler

@BAGaucho wrote:

Thanks for such a quick response. Sorry about vague description. Yes, 5 groups for solid color without any pattern and two new groups with colors with pattern. That's what I need to do.

 

I saw the proc template example before I posted but didn't noticed I can use fillpattern='S'. If we can use fillpattern='S', I wonder why I can't use datafillpatterns=(S S S S S X1 L1)? It seems that SGPlot removed the pattern options S & E. 

You should provide example data, so we can actually test code against,  and the entire code you attempted. Please provide data in the form of data step code and paste all code into a text box opened on the forum with the </> icon to preserve formatting. Sometimes code pasted into the main message window will not run because of text reformatting by the forum resulting in non-printable characters or changing white space characters.

BAGaucho
Obsidian | Level 7

Thanks for offering to test my code. I can create sample data and code so you can test it. However, my main issue is the pattern values in datafillpatterns option. There are only 15 cases (X1-X5, L1-L5, and R1-R5). In your Proc Template example, I see S or E but why datafillpatterns doesn't have S or E?

 

Also, I don't like to use proc template but love to use "Discrete Attribute Map data" if needed. What will be the method to use pattern option? I tried "fillpattern variable", but it seems no effect.

 

If you have any answer for the two cases, I really appreciate.

ballardw
Super User

Please:

Data

Proc gplot  code

dattrmap data set code

 

BAGaucho
Obsidian | Level 7

OK, I made an example code to test both method (attrmap and styleattrs) with an example data.

 

data test;
length seq trt trta $10;
input cfb seq $ trt $ trta $;

cards;
78.9 01 30KG 30KG
63.8 04 20KG 20KG
22.7 02 20KG 20KG
16.1 07 30KG 30KG
6.8 06 20KG 20KG
5.5 08 20KG 20KG
2.2 13 20KG 20KG
2 10 40KG 40KG
0.9 12 20KG 20KG
-0.9 16 40KG 40KG
-1.7 14 20KG 20KG
-2.3 19 30KG 30KG
-10.9 18 30KG 30KG
-18.3 25 10KG 10KG
-24.5 20 50KG 50KG
-25.9 26 20KG 20KG
-27.7 24 20KG 20KG
-28.7 28 40KG 40KG
-31.9 31 10KG 10KG
-33.4 22 30KG 30KG
-54.6 30 30KG 30KG
-61.9 32 40KG 40KG
;
run;

data attrmap;
length ID $ 9 fillcolor $ 20;
input id $ value $10-20 fillcolor $ fillpattern $;

datalines;
trta 10KG red S
trta 20KG blue S
trta 30KG green L1
trta 40KG purple X1
trta 50KG orange R1
;
run;

proc sgplot data=test dattrmap=attrmap;
*styleattrs datacolors=(red blue green purple orange) datafillpatterns=(S S X1 R1 L1);
vbarparm category=seq response=cfb / group=trt attrid=trta name='a' fillpattern;

xaxis display=(nolabel noticks) ;
yaxis display=(nolabel) min=-100 max=100 ;

keylegend 'a' / noborder location=inside position=topright across=1 ;
run;

 

This works fine but no pattern effect at all.

 

Then if comment out the dattrmap and used styleattrs statement, I got this error message.

 

BAGaucho_0-1677609673322.png

So, I assume datafillpatterns option does not include S as solid. Just X1-X5, L1-L5 and R1-R5. I don't understand why SAS didn't keep S and E options as the good old SAS/Graph pattern statement. I would like to use the mixed cased (solid and pattern).

 

 

ballardw
Super User

Your dattrmap data set as posted does not run correctly. You should post code into a text box opened on the forum with the </> icon that appears above the message to prevent text from getting reformatted. The forum will reformat text pasted into the main message window, typically playing with white space.

 

In this case your fixed columns for reading the Value start after the 10Kg and so read part or all of the Fillcolor and pattern text for value. Then continue on to the next line to read the color and pattern ending up with color = trta (not valid in any of the color schemes SAS uses) and only 2 observations.

BAGaucho
Obsidian | Level 7

I give up. Nobody suggested any method how to solve my issue. 

ballardw
Super User

When you look at the documentation for DATTRMAP variables at https://documentation.sas.com/doc/en/pgmsascdc/9.4_3.4/grstatproc/n18szqcwir8q2nn10od9hhdh2ksj.htm#p...  the section starting Description of the Reserved Variables you will see that there is no fill pattern variable. So Dattrmap is out.

And the documentation for Style datafillpatterns does not include S, which agrees with the error you get.

 

The bar chart I showed using GTL will allow a solid bar, just a bit more work.

 

Another option might be to overlay a second Vbarparm with only the desired TRTA (need a new variable for the Response only set on those and not use patterns. But you will likely lose a simple way to get the Keylegend to match.

 

I am not sure but the line pattern fills are traditionally more for monochrome display where you can't get enough contrast to identify specific bars based on color or shades of color. So that may be why SAS in SGPLOT has decided to support the Solid or Empty bars.

BAGaucho
Obsidian | Level 7

Thank you! I suspected that DATTRMAP doesn't have the fill pattern variable although I am not getting any error message. Also, it's shame that SAS doesn't include S or E for Style datafillpatterns. Yeah, I guess GTL can do that but I am not good at GTL and don't want to use GTL unless I REALLY need to use it. I agree with you to use two vbarparm statements and I actually thought about it but I was looking for any easier and clear solution. I will try your last suggestion.

 

Thanks!

BAGaucho
Obsidian | Level 7

I am leaving this for anyone who may need it in the future...

 

With ballardw's suggestion, I tried many different combinations of codes. Finally, I came up with what I needed using two vbarparm statements but not that simple as I expected. If SAS company add S and E options to datafillpatterns in styleattrs statement or fillpattern variable in ATTRMAP data, it would be super easy task.

 

This is what I ended up doing...

1. For the first vbarparm, I listed all groups with proper colors I want (using either ATTRMAP or styleattrs)

2. For the second vbarparm, I had to trick the data. Need to create a trt2 variable and I made the response variable (my case is cfb but created a temp variable as cfb2) value to be zero so it will not overwrite other groups (solid color group).  I still need to specify fillpattern fillpatternattrs=(pattern=r1) nofill options to put pattern to second groups. Still I cannot use multiple patterns but only one since I can only specify one pattern for fillpatternattrs option.

3. I cannot use Keylegend statement anymore so I have to create multiple legenditem statements per individual group

 

Yes, I managed to create a bar plot with both solid color with and without pattern, but this should be super easy if we have one extra option. I hope SAS can add this option someday.  

 

Cheers!

sas-innovate-2024.png

 

Time is running out to save with the early bird rate. Register by Friday, March 1 for just $695 - $100 off the standard rate.

 

Check out the agenda and get ready for a jam-packed event featuring workshops, super demos, breakout sessions, roundtables, inspiring keynotes and incredible networking events. 

 

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
  • 11 replies
  • 1495 views
  • 3 likes
  • 2 in conversation