11-18-2013 11:31 AM
I'm making a 100% Stacked Bar Chart with an axistable below it (to avoid labeling the bars which gets messy). By default, the order of the two are opposing; the bar chart puts the lower number on the bottom while the axistable puts the lower number on top. I was hoping to be able to reorder the axis table by reversing the Y axis for that table, but unfortunately don't seem to be able to (I'm guessing the axistable isn't even using the Y axis, for obvious reasons).
I figured out two workarounds, but neither is optimal for my particular usage. One is to reverse the Y axis on the *barchart*, which does make the two match; but I prefer lower numbers on bottom. The second is to sort the dataset by the two variables but descending the second variable; in combination with reversing the Y axis on the barchart, this makes it look correct as long as I have the same categories exactly for each bar, which my data should. However, that sort itself is undesirable for the effects it has on my other charts, and I can't afford to re-sort the data twice for every set of charts as I'm making a few hundred thousand slides in total.
Is there a way to reverse the axistable, or am I stuck with one of the workarounds above (or a different/better one?)
The below code shows my example and a couple of workarounds.
define statgraph test;
begingraph/datacolors=(cxFF0000 cx00FF00 cx0000FF cxFFFF00 cxFF00FF cx00FFFF cxBBBBBB cx555555)
datacontrastcolors=(cxFF0000 cx00FF00 cx0000FF cxFFFF00 cxFF00FF cx00FFFF cxBBBBBB cx555555);
layout overlay/ /*yaxisopts=(reverse=1)*/ xaxisopts=(display=none); *WORKAROUND 1 and 2 - uncomment yaxisopts;
barchart x=sex y=pctval/group=age;
layout overlay / walldisplay=none xaxisopts=( display=none griddisplay=off offsetmin=.1 offsetmax=.1)
yaxisopts=(display=(tickvalues) offsetmin=.2 offsetmax=0 reverse=1)
AxisTable x=sex value=pctval/
class="age" colorGroup=age Display=(Label);
proc tabulate data=sashelp.class;
where age le 15;
class sex age;
ods output table=classpct(keep=sex age pct;
/* WORKAROUND 2 - uncomment this sort.
proc sort data=classpct;
by sex descending age ;
proc sgrender data=classpct template=test;
11-18-2013 12:57 PM
In your specific case, where group and class variable are nuumeric, you can use GROUPORDER=descending on the bar chart to reverse the order. But, in general for such a case, we likely need an option to set (or at least reverse) the "Class" order on the AxisTable.
Still, it is good to see a question on the new SAS 9.4 statement.
barchart x=sex y=pctval/group=age grouporder=descending;
11-18-2013 01:02 PM
Thanks, Sanjay. That seems to be effectively identical to reversing the Y axis from my point of view, no? (ie, it makes the barchart reverse, rather than the axistable reverse which is my preference). I would look forward to seeing that option in a future release for the axis table Enjoying 9.4 GTL quite a lot, lots of useful new stuff in there.
9.3 used a scatterplot for the axistable, didn't it? Is that something that could be easily used and reordered?
11-18-2013 01:21 PM
Hmm, actually a BlockPlot. Starting from Leroy Bessler's example where I saw this first (http://www.mwsug.org/proceedings/2012/DV/MWSUG-2012-DV13.pdf page 35 or so):
proc sgplot data=sashelp.stocks tmplout="c:\temp\test.txt";
where date ge '01JAN2005'd;
vline date / response=close group=stock
markers markerattrs=(size=7 symbol=circlefilled)
datalabelattrs=(family='Albany AMT/Bold' size=10 PT weight=Bold)
keylegend / noborder
titleattrs=(family='Albany AMT/Bold' size=12 PT)
valueattrs=(family='Albany AMT/Bold' size=12 PT);
yaxis display=(nolabel noticks noline) grid
offsetmin=0.05 /* space between top of datalabel table & bottom of plot area */
valueattrs=(family='Albany AMT/Bold' size=12 PT);
xaxis display=(nolabel noticks noline) grid
valueattrs=(family='Albany AMT/Bold' size=12 PT) values=(1 to 12 by 1);
format close 5.;
That takes me to this template code:
define statgraph sgplot;
EntryTitle " " /;
layout overlay / xaxisopts=( griddisplay=on display=( tickvalues ) TickValueAttrs=( Size=12pt Family="Albany AMT/Bold") type=discrete discreteopts=( tickValueList=_ticklist_ ) ) yaxisopts=( griddisplay=on display=( tickvalues ) offsetmin=0.05 TickValueAttrs=( Size=12pt Family="Albany AMT/Bold") type=auto ) x2axisopts=(type=Discrete discreteOpts=(tickValueList=_ticklist_));
SeriesPlot X=Date Y=_Sum1_Close_ / primary=true Group=Stock display=(markers) Markerattrs=( Symbol=CIRCLEFILLED Size=7) Lineattrs=( Pattern=1 Thickness=3) LegendLabel="Close (Sum)" NAME="VLINE";
innermargin / align=bottom;
blockplot x=Date block=_Sum1_Close_ / class="Stock" display=(label values)
valueHalign=center repeatedValues=true valueFitPolicy=shrink LabelAttrs=GraphValueText
LabelAttrs=GraphDataText( Family="Albany AMT/Bold" Size=10 Weight=bold )
ValueAttrs=GraphDataText( Family="Albany AMT/Bold" Size=10 Weight=bold );
DiscreteLegend "VLINE" / Location=Outside TitleAttrs=( Size=12pt Family="Albany AMT/Bold") ValueAttrs=( Size=12pt Family="Albany AMT/Bold") Border=false;
The blockplot unfortunately doesn't look like it has reverse options either, nor does it reverse with the y-axis reversing.
11-18-2013 02:56 PM
Since sorting the original data could have other side effects, it may be better to use the option.
Yes, you can still use SCATTERPLOT with MARKERCHARACTER option to do your table, but then you cannot use the PREFERRED option for RowWeights. Also, you can color the values, but not the labels.
BLOCKPLOT could work, but you cannot color the values.
11-18-2013 03:12 PM
Also, as an aside, AXISTABLE's DISPLAY option is slightly quirky. DISPLAY=NONE is invalid in this context, and while I realize DISPLAY=STANDARD is probably roughly equivalent to that if you require the value labels, it would be nice if NONE was a synonym for that if nothing else - it was confusing to eventually realize I had to use DISPLAY=STANDARD which I basically never use.
11-18-2013 03:29 PM
Sure, but I wanted to use DISPLAY=NONE and kept getting errors I'm just suggesting including it, even if it does nothing, just to avoid people being confused by the inconsistency with most of the other plot types.