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

There was an interesting question on LinkedIn, where the desire was to fill the peaks of a series plot with one color, and the valleys as another color.

 

https://www.linkedin.com/feed/update/urn:li:activity:6783694808239128576

 

Fill.png

 

I'm wondering how folks would approach this.

 

Graphing guru Kriss Harriss had the good idea of using bandplot, and posted the approach in his excellent Daily Coding series:

https://www.linkedin.com/posts/krissharris_dailycoding-day91-sgf-activity-6783513455380041728-vO9n

 

When I played with this, I started with a sine wave and the goal of coloring the peaks and valleys different colors, without specifying the x-values to define each peak.  I got close to what I wanted, but unfortunately there is no /BREAK option for the band statement, so SGPLOT connects the peaks.

 

My code:

 

data foo;
  do x = 0 to 3.14*4 by 0.01;
    y = sin(x);   
    output;
  end;
run;

data foo2 ; 
  set foo ;
  if y > .5 then do ;
    group=1 ;
    limit=.5 ;
  end ;
  else if y < -.75 then do ;
    group= 2 ;
    limit= -.75 ;
  end ;
run ;

proc sgplot data=foo2 ;
  series x=x y=y ;
  band x = x lower = limit upper = y   / group=group nomissinggroup;
run ;

My output, within the unwanted connecting bands highlighted:

Fill2.png

 

I thought this was an interesting question, so was curious about other approaches.

 

Since the OP has reference lines for each band, I think my approach might actually 'work' because you could make the reference lines cover the unwanted band lines.

 

BASUG is hosting free webinars ! Check out recordings of our past webinars: https://www.basug.org/videos. Save the date for our in person SAS Blowout on Oct 18 in Cambridge, MA. Registration opens in September.
1 ACCEPTED SOLUTION

Accepted Solutions
PGStats
Opal | Level 21

I guess you could do:

 

data foo;
  do x = 0 to 3.14*4 by 0.01;
    y = sin(x) + 10;   
    output;
  end;
run;

data foo2 ; 
  set foo ;
  output;
  t = x; x = .;
  do Limit = 9.7, 9.2, 10.5, 10.75;
    if (y-10) / (limit-10) > 1 then z = y;
    else z = limit;
    output;
  end ;
run ;

proc sgplot data=foo2 ;
  band x = t lower = limit upper = z / group=limit nomissinggroup;
  series x = x y = y ;
run ;

PGStats_0-1617474533408.png

Note that the order is important in the list of limits, so that the more extreme values are named last.

 

PG

View solution in original post

6 REPLIES 6
FreelanceReinh
Jade | Level 19

Hello @Quentin,

 

It looks like Simon Bacha opened an own thread about this the day before yesterday and that @PGStats's solution avoids the problem of the connecting lines. I'm still trying to understand the trick, but it seems that the way he defines the limits is about as important as omitting the GROUP= option (and using two BAND statements instead).

 

Something like this:

data foo2 ; 
  set foo ;
  limit1 = min(y, .5) ;
  limit2 = max(y, -.75) ;
run ;

proc sgplot data=foo2 ;
  series x=x y=y ;
  band x = x lower = limit1 upper = y / fillattrs=(color=CX6F7EB3) legendlabel='Group 1' ;
  band x = x lower = limit2 upper = y / fillattrs=(color=CXD05B5B) legendlabel='Group 2' ;
run ;
PGStats
Opal | Level 21

Add options nooutline noextend to the band statement to get rid of the colored lines.

PG
FreelanceReinh
Jade | Level 19

@PGStats wrote:

Add options nooutline noextend to the band statement to get rid of the colored lines.


Thanks, @PGStats, for chiming in. These two options didn't seem to have an impact on the graph (with Quentin's data), which is why I omitted them for simplicity:

SGPlot34.png

Of course, it doesn't hurt to include them and they could be important in other situations.

Quentin
Super User

As @FreelanceReinh mentioned, adding NOOUTLINE NOEXTEND doesn't avoid the connecting line.

 

It looks like your nifty solution avoids the connecting line by having data where the upper value and the lower value are the same, so I suspect SGPLOT is drawing a band with height 0.  So for my approach using group, the hack would be to add records for each group, something like:

 

data foo2 ; 
  set foo ;
  if y > .5 then do ;
    group=1 ;
    limit=.5 ;
output ; end ; else if y < -.75 then do ; group= 2 ; limit= -.75 ; output ;
end ; else do ; limit=y ; group=1 ; output ; group=2 ; output ; end ; run ; proc sgplot data=foo2 ; series x=x y=y ; band x = x lower = limit upper = y / group=group nomissinggroup ; run ;

So in the absence of a /break option, looks like a band of height 0 achieves the same effect. 

 

But your solution in the other thread is better than this one!

BASUG is hosting free webinars ! Check out recordings of our past webinars: https://www.basug.org/videos. Save the date for our in person SAS Blowout on Oct 18 in Cambridge, MA. Registration opens in September.
PGStats
Opal | Level 21

I guess you could do:

 

data foo;
  do x = 0 to 3.14*4 by 0.01;
    y = sin(x) + 10;   
    output;
  end;
run;

data foo2 ; 
  set foo ;
  output;
  t = x; x = .;
  do Limit = 9.7, 9.2, 10.5, 10.75;
    if (y-10) / (limit-10) > 1 then z = y;
    else z = limit;
    output;
  end ;
run ;

proc sgplot data=foo2 ;
  band x = t lower = limit upper = z / group=limit nomissinggroup;
  series x = x y = y ;
run ;

PGStats_0-1617474533408.png

Note that the order is important in the list of limits, so that the more extreme values are named last.

 

PG

SAS Innovate 2025: Call for Content

Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 16. Read more here about why you should contribute and what is in it for you!

Submit your idea!

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
  • 6 replies
  • 893 views
  • 4 likes
  • 4 in conversation