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

I have a dataset like: timestamp | VAR1 | VAR2 | VAR3.

 

I'd like to plot three series (timestamp,VAR1), (timestamp, VAR2), (timestamp, VAR3) in three graphs stacked vertically, so that the y axes, which may have different scales and unit of measures, should be aligned on a vertical line.

The purpose is that if I want to see what happens at a specific timestamp, I just look at the three series "vertically" on an imaginary vertical line.

So far I did three sequentially sgplots, but since the y axes values may occupy different spaces (e.g. the size of "1" "2" "3" is smaller than "1000" "2000 "3000"), the three graphs are not vertically aligned.

 

How can I achieve that?

I hope I made myself clear.

Thanks

Regards

1 ACCEPTED SOLUTION

Accepted Solutions
Rick_SAS
SAS Super FREQ

I understand now. No, I do not know how to do that when you create individual graphs. The correct way to do it is to transpose the data and use SGPANEL

 


proc transpose 
   data=Have
   out=Want(drop=_LABEL_ rename=(Col1=Value)) /* 2 */
   name=Variable;                             /* 3 */
   by timestamp;                              /* original X var  */
   var A B C;                                 /* original Y vars */
run;

ods graphics / reset;
/* plot on a single scale in multiple graphs */
proc sgpanel data=Want;
    panelby Variable / UNISCALE=COLUMN columns=1;
    series x=timestamp y=Value;
run;

 

View solution in original post

15 REPLIES 15
Edoedoedo
Pyrite | Level 9
Thanks I taught about it, however I couldn't figure out how to use it in this case, there is no groups to use in panelby and I don't want to restructure the dataset if not absolutely necessary.

Can you give me an example of how should I use sgpanel here?

Thanks
Reeza
Super User

@Edoedoedo wrote:
Thanks I taught about it, however I couldn't figure out how to use it in this case, there is no groups to use in panelby and I don't want to restructure the dataset if not absolutely necessary.

Can you give me an example of how should I use sgpanel here?

Thanks

Sure, can you please provide sample data?

Here are instructions on how to provide sample data as a data step:
https://communities.sas.com/t5/SAS-Communities-Library/How-to-create-a-data-step-version-of-your-dat...

Edoedoedo
Pyrite | Level 9

Sure, since the dataset is very simple I assumed it could be discussed just knowing the dataset metadata!

 

Here's the dataset and my code so far:

 data HAVE;
   format timestamp datetime25.;
timestamp=datetime(); A=1; B=500000; C=0.03; output;
timestamp=datetime()+60; A=2; B=100000; C=0.05; output;
timestamp=datetime()+120; A=3; B=300000; C=0.01; output;
timestamp=datetime()+180; A=4; B=400000; C=0.02; output;
timestamp=datetime()+240; A=5; B=200000; C=0.04; output;
run;

proc sgplot data=have;
    series x=timestamp y=A;
run;
proc sgplot data=have;
    series x=timestamp y=B;
run;
proc sgplot data=have;
    series x=timestamp y=C;
run;

 

As you can see the three graphs are not vertically aligned on y axes.

Moreover, I'd prefer not to create an ad-hoc temporary table, since it would require more time (in real data rows are millions and columns A B C are some dozens).

 

Thanks

Rick_SAS
SAS Super FREQ

It sounds like you want to plot all graphs on the same scale? For example, the Y axis should be [0, 50000] for all graphs?

 

As Reeza says, SGPANEL makes this easy if you convert form "Wide" data to "Long" data.

However, if you do not want to convert, you can either put all graphs in a single graph or you can use the YAXIS statement to set the Y axis to be the same for individual graphs:

 

/* plot on a single scale in one graph */
proc sgplot data=have;
    series x=timestamp y=A;
    series x=timestamp y=B;
    series x=timestamp y=C;
run;


/* plot on a single scale in multiple graphs */
%let minY = 0;
%let maxY = 500000;
proc sgplot data=have;
    series x=timestamp y=A;
    yaxis min=&minY max=&maxY;
run;
proc sgplot data=have;
    series x=timestamp y=B;
    yaxis min=&minY max=&maxY;
run;
proc sgplot data=have;
    series x=timestamp y=C;
    yaxis min=&minY max=&maxY;
run;
Edoedoedo
Pyrite | Level 9

No, I don't want to use the same scale for all graphs, every one should have its own scale. But if I look at the y axes vertically, they should be aligned.

Let me attach an image to explain what I mean:align.png

Rick_SAS
SAS Super FREQ

Sorry to keep asking questions, but do you mean that you want the X axis aligned? In your example, it looks like you want to ensure that the range of the X axis is always consistent for all of the plots. In that case, you should use 

 

/* get min and max of X */
proc sql;
select min(timestamp), max(timestamp)
      into :minX, :maxX
      from Have;
run;

/* plot on a single scale in multiple graphs */
proc sgplot data=have;
    series x=timestamp y=A;
    xaxis min=&minX max=&maxX;
run;
proc sgplot data=have;
    series x=timestamp y=B;
    xaxis min=&minX max=&maxX;
run;
proc sgplot data=have;
    series x=timestamp y=C;
    xaxis min=&minX max=&maxX;
run;

Edoedoedo
Pyrite | Level 9

Maybe it's clear in my head but I'm not succeeding in explain it 😄

 

However no, in my example the x axis values are exactly the same for all three graphs, so setting min and max wouldn't change anything since the min and the max are already reached by all three graphs.

 

What I mean is that since the three vars have different scale (and that's ok), when the sgplot draws the y axis, it is drawn "more to the right" depending on what it has to plot on the left of the y axis, that is the numbers of the scale.

 

In the first graph, the numbers on the left are "1" "2" "3",... assume they occupy 10px, then there is a white space, assume it occupies 5px, and then the y axis: so it begins in the paper at coordinate 15px.

 

In the second graph, the numbers in the left are "100000" "200000" etc, so they occupy MORE space, assume 10px * 6 digits = 60px, then there is a white space, assume it occupies 5px as before, and then the y axis: so it begins in the paper at coordinate 65px.

 

Hence the two y axes are not aligned vertically! One is at 15px, one is at 65px.

 

My question is how to "center" the graphs so that the y axes are exactly at the same distance in pixel from the left of the paper. 

Rick_SAS
SAS Super FREQ

I understand now. No, I do not know how to do that when you create individual graphs. The correct way to do it is to transpose the data and use SGPANEL

 


proc transpose 
   data=Have
   out=Want(drop=_LABEL_ rename=(Col1=Value)) /* 2 */
   name=Variable;                             /* 3 */
   by timestamp;                              /* original X var  */
   var A B C;                                 /* original Y vars */
run;

ods graphics / reset;
/* plot on a single scale in multiple graphs */
proc sgpanel data=Want;
    panelby Variable / UNISCALE=COLUMN columns=1;
    series x=timestamp y=Value;
run;

 

Edoedoedo
Pyrite | Level 9
Thanks that's exactly what I needed!

However I'm getting this error for proc transpose:

ERROR: One or more ID variables are required.
ERROR: Failure during action initialization.
ERROR: The action stopped due to errors.

since the table is in CAS. In SAS 9.4 it works, but in CAS it says the id parameter is required. What's wrong?
Rick_SAS
SAS Super FREQ
Please post the exact program which gives the error.
Edoedoedo
Pyrite | Level 9

Same as the previous, but with a CAS library (instead of work):

 

cas session;
libname CASUSER cas caslib="CASUSER";

data CASUSER.HAVE;
   format timestamp datetime25.;
timestamp=datetime(); A=1; B=500000; C=0.03; output;
timestamp=datetime()+60; A=2; B=100000; C=0.05; output;
timestamp=datetime()+120; A=3; B=300000; C=0.01; output;
timestamp=datetime()+180; A=4; B=400000; C=0.02; output;
timestamp=datetime()+240; A=5; B=200000; C=0.04; output;
run;


proc transpose 
   data=CASUSER.Have
   out=CASUSER.Want
   name=Variable;
   by timestamp;
   var A B C;
run;

ods graphics / reset;
/* plot on a single scale in multiple graphs */
proc sgpanel data=CASUSER.Want;
    panelby Variable / UNISCALE=COLUMN columns=1;
    series x=timestamp y=Col1;
run;
ERROR: One or more ID variables are required.
ERROR: Failure during action initialization.
ERROR: The action stopped due to errors.
NOTE: The Cloud Analytic Services server processed the request in 0.046021 seconds.
NOTE: The SAS System stopped processing this step because of errors.
NOTE: PROCEDURE TRANSPOSE ha utilizzato (tempo totale di elaborazione):
      real time           0.15 seconds
      cpu time            0.05 seconds
Rick_SAS
SAS Super FREQ

You can add a unique identifier to each observation and use that as the ID variable:

 


data casuser.HAVE;
   format timestamp datetime25.;
ID = _N_; timestamp=datetime(); A=1; B=500000; C=0.03; output;
ID = _N_; timestamp=datetime()+60; A=2; B=100000; C=0.05; output;
ID = _N_; timestamp=datetime()+120; A=3; B=300000; C=0.01; output;
ID = _N_; timestamp=datetime()+180; A=4; B=400000; C=0.02; output;
ID = _N_; timestamp=datetime()+240; A=5; B=200000; C=0.04; output;
run;

proc transpose 
   data=CASUSER.Have
   out=CASUSER.Want
   name=Variable;
   by timestamp;
   id ID;
   var A B C;
run;

proc contents short data=casuser.want;
run;

/* plot on a single scale in multiple graphs */
proc sgpanel data=casuser.Want(rename=(_1=Value));
    panelby Variable / UNISCALE=COLUMN columns=1;
    series x=timestamp y=Value;
run;
Edoedoedo
Pyrite | Level 9
Thanks it works great.
I'll flag as solution the previous answer since this is a collateral issue CAS related.

Regards

SAS Innovate 2025: Register Now

Registration is now open for SAS Innovate 2025 , our biggest and most exciting global event of the year! Join us in Orlando, FL, May 6-9.
Sign up by Dec. 31 to get the 2024 rate of just $495.
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
  • 15 replies
  • 3476 views
  • 4 likes
  • 3 in conversation