Pyrite | Level 9

## Plot multiple series stacked vertically with y axes aligned

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
SAS Super FREQ

## Re: Plot multiple series stacked vertically with y axes aligned

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;
``````

15 REPLIES 15
Super User

SGPANEL
Pyrite | Level 9

## Re: Plot multiple series stacked vertically with y axes aligned

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
Super User

## Re: Plot multiple series stacked vertically with y axes aligned

@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...

Pyrite | Level 9

## Re: Plot multiple series stacked vertically with y axes aligned

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

SAS Super FREQ

## Re: Plot multiple series stacked vertically with y axes aligned

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;``````
Pyrite | Level 9

## Re: Plot multiple series stacked vertically with y axes aligned

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:

SAS Super FREQ

## Re: Plot multiple series stacked vertically with y axes aligned

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;

``````
Pyrite | Level 9

## Re: Plot multiple series stacked vertically with y axes aligned

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.

SAS Super FREQ

## Re: Plot multiple series stacked vertically with y axes aligned

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;
``````

Pyrite | Level 9

## Re: Plot multiple series stacked vertically with y axes aligned

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?
SAS Super FREQ

## Re: Plot multiple series stacked vertically with y axes aligned

Please post the exact program which gives the error.
Pyrite | Level 9

## Re: Plot multiple series stacked vertically with y axes aligned

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``````
SAS Super FREQ

## Re: Plot multiple series stacked vertically with y axes aligned

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;
``````
Pyrite | Level 9

## Re: Plot multiple series stacked vertically with y axes aligned

Thanks it works great.
I'll flag as solution the previous answer since this is a collateral issue CAS related.

Regards
Discussion stats
• 15 replies
• 3053 views
• 4 likes
• 3 in conversation