BookmarkSubscribeRSS Feed
tc
Lapis Lazuli | Level 10 tc
Lapis Lazuli | Level 10

PresidentialElection.png

 

Oh, there's no place like SAS ODS Graphics for the Holidays. 🙂

 

So, with Halloween coming up, here's a states-as-jack-o-lanterns makeover of CNN's 2016 Electoral Map. It's kind of a remix of The United Polygons of America, but using SYMBOLIMAGE instead of polygons.

 

In the immortal words of Count Floyd, "Oooh, wasn't that scary, kids?"

 

*==> Tile Map of 2016 Presidential Election w/States as Pumpkins!; 

*==> US tile map coordinates from Matt Chambers
     drive.google.com/file/d/0B24QRdfcy_JJZFRKLUZzMHZYbG8/view;

data StateGrid;
input statecode : $2. row column@@;
row=-row;       * Flip map's y-coordinates (FL at bottom, ME at top!);
row=.95*row;    * Tighten up line spacing;
cards;
AK 0 0.5 ME 0 11.5        
VT 1 10 NH 1 11        
WA 2 1.5 MT 2 2.5 ND 2 3.5 MN 2 4.5 WI 2 5.5 MI 2 7.5 NY 2 9.5 MA 2 10.5 RI 2 11.5 
ID 3 2 WY 3 3 SD 3 4 IA 3 5 IL 3 6 IN 3 7 OH 3 8 PA 3 9 NJ 3 10 CT 3 11
OR 4 1.5 NV 4 2.5 CO 4 3.5 NE 4 4.5 MO 4 5.5 KY 4 6.5 WV 4 7.5 MD 4 8.5 DE 4 9.5 
CA 5 2 AZ 5 3 UT 5 4 KS 5 5 AR 5 6 TN 5 7 VA 5 8 NC 5 9 DC 5 12 
NM 6 3.5 OK 6 4.5 LA 6 5.5 MS 6 6.5 AL 6 7.5 SC 6 8.5    
TX 7 4 GA 7 8        
HI 8 0.5 FL 8 8.5 
;
*==> Get state predictions (cnn.com/election/interactive-electoral-college-map, updated oct 19, 2016 4:00 pm et);

data StateDR(keep=prediction statecode);
length statecode $ 2;
input prediction $char17.;
do s=1 to 51;
  statecode=scan(substr(_infile_,18),s);
  if statecode^='' then output;
end;     
cards;
Leans Democrat   CO FL MI NH NV PA VA WI             
Solid Democrat   CA CT DC DE HI IL MA MD ME MN NJ NM NY OR RI VT WA  
Leans Republican GA IA                  
Solid Republican AK AL AR ID IN KS KY LA MO MS MT ND NE OK SC SD TN TX WV WY
Battleground     AZ NC OH UT
;     
*==> Merge map coordinates and CNN predictions;

proc sql;
create table stategridDR as 
select sg.*, sd.prediction
from stategrid sg, statedr sd where sg.statecode=sd.statecode;

*==> Draw the map (map predictions to colored pumpkins);

ods listing image_dpi=300 gpath='/folders/myfolders';
ods graphics on / reset antialias width=11in height=8.5in imagename="PresidentialElection";

proc template;
define statgraph ustemplate;
  begingraph;
  symbolimage name=symPLD image="/folders/myfolders/PumpkinLightBlue.png";
  symbolimage name=symPSD image="/folders/myfolders/PumpkinBlue.png";
  symbolimage name=symPLR image="/folders/myfolders/PumpkinLightRed.png";
  symbolimage name=symPSR image="/folders/myfolders/PumpkinRed.png";
  symbolimage name=symPBG image="/folders/myfolders/PumpkinOrange.png";
  discreteattrmap name="symbols" / ignorecase=true trimleading=true;
    value "Leans Democrat" / markerattrs=(symbol=symPLD size=47pt);
    value "Solid Democrat" / markerattrs=(symbol=symPSD size=47pt);
    value "Leans Republican" / markerattrs=(symbol=symPLR size=47pt);
    value "Solid Republican" / markerattrs=(symbol=symPSR size=47pt);
    value "Battleground" / markerattrs=(symbol=symPBG size=47pt);
  enddiscreteattrmap;
  discreteattrvar attrvar=groupmarkers var=prediction attrmap="symbols";
  legendItem type=marker name="psd" / markerattrs=(symbol=symPSD size=24pt) label="SOLID (D)" labelattrs=(size=9pt weight=bold);
  legendItem type=marker name="pld" / markerattrs=(symbol=symPLD size=24pt) label="LEANS (D)" labelattrs=(size=9pt weight=bold);
  legendItem type=marker name="pbg" / markerattrs=(symbol=symPBG size=24pt) label="BATTLEGROUND" labelattrs=(size=9pt weight=bold);
  legendItem type=marker name="plr" / markerattrs=(symbol=symPLR size=24pt) label="LEANS (R)" labelattrs=(size=9pt weight=bold);
  legendItem type=marker name="psr" / markerattrs=(symbol=symPSR size=24pt) label="SOLID (R)" labelattrs=(size=9pt weight=bold);
  layout overlayequated / border=false xaxisopts=(display=none) yaxisopts=(display=none);
    entry "2016 Electoral Map (Source: CNN, 10-22-2016)" / valign= top textattrs=(size=16pt weight=bold);
    scatterplot x=column y=row / group=groupmarkers;
    textplot x=column y=row text=statecode / position=top textattrs=(color=black size=9.5pt weight=bold);
    discretelegend "psd" "pld" "pbg" "plr" "psr" / location=inside border=true valign=bottom;
  endlayout;
  endgraph;
end;
run;

proc sgrender data=stategridDR template=ustemplate;

 

3 REPLIES 3
Jay54
Meteorite | Level 14

Very cool, TC.  

 

Just wondering if you could have used STYLEATTRS DATASYMBOLS=(sympld sympsd ...) to make the pumplins into group symbols and  also get these in the legend automatically?  If I had your full code (with images), I could have tried it out.

tc
Lapis Lazuli | Level 10 tc
Lapis Lazuli | Level 10

As things turn out, yes I could have, and it indeed greatly simplifies things! I wasn't aware of this feature, but a quick google turned up a blog post of yours on the subject (Infographics Using SAS), which I followed to come up with the below look-Ma-no-GTL solution. Always learn something from these SAS Communities "code reviews"! Smiley Happy

 

REVISED IMAGE

ElectoralMap.png

 

SIMPLIFIED CODE

*==> Tile Map of 2016 Presidential Election w/States as Pumpkins!; 

*==> US tile map coordinates from Matt Chambers
     drive.google.com/file/d/0B24QRdfcy_JJZFRKLUZzMHZYbG8/view;

data StateGrid;
input statecode : $2. row column@@;
row=-row;       * Flip map's y-coordinates (FL at bottom, ME at top!);
row=.95*row;    * Tighten up line spacing;
cards;
AK 0 0.5 ME 0 11.5        
VT 1 10 NH 1 11        
WA 2 1.5 MT 2 2.5 ND 2 3.5 MN 2 4.5 WI 2 5.5 MI 2 7.5 NY 2 9.5 MA 2 10.5 RI 2 11.5 
ID 3 2 WY 3 3 SD 3 4 IA 3 5 IL 3 6 IN 3 7 OH 3 8 PA 3 9 NJ 3 10 CT 3 11
OR 4 1.5 NV 4 2.5 CO 4 3.5 NE 4 4.5 MO 4 5.5 KY 4 6.5 WV 4 7.5 MD 4 8.5 DE 4 9.5 
CA 5 2 AZ 5 3 UT 5 4 KS 5 5 AR 5 6 TN 5 7 VA 5 8 NC 5 9 DC 5 12 
NM 6 3.5 OK 6 4.5 LA 6 5.5 MS 6 6.5 AL 6 7.5 SC 6 8.5    
TX 7 4 GA 7 8        
HI 8 0.5 FL 8 8.5 
;
*==> Get state predictions (cnn.com/election/interactive-electoral-college-map, updated oct 19, 2016 4:00 pm et);

data StateDR(keep=prediction statecode);
length statecode $ 2;
input prediction $char17.;
do s=1 to 51;
  statecode=scan(substr(_infile_,18),s);
  if statecode^='' then output;
end;     
cards;
BATTLEGROUND     AZ NC OH UT
LEANS (D)        CO FL MI NH NV PA VA WI             
LEANS (R)        GA IA                  
SOLID (D)        CA CT DC DE HI IL MA MD ME MN NJ NM NY OR RI VT WA  
SOLID (R)        AK AL AR ID IN KS KY LA MO MS MT ND NE OK SC SD TN TX WV WY
;     
*==> Merge map coordinates and CNN predictions;

proc sql;
create table stategridDR as 
select sg.*, sd.prediction
from stategrid sg, statedr sd where sg.statecode=sd.statecode order by sd.prediction;

*==> Draw the map (map predictions to colored pumpkins);

ods listing image_dpi=300 gpath='/folders/myfolders';
ods graphics on / reset antialias width=11in height=8.5in attrpriority=none imagename="ElectoralMap";
proc sgplot data=stategridDR noborder;
symbolimage name=symPLD image="/folders/myfolders/PumpkinLightBlue.png";
symbolimage name=symPSD image="/folders/myfolders/PumpkinBlue.png";
symbolimage name=symPLR image="/folders/myfolders/PumpkinLightRed.png";
symbolimage name=symPSR image="/folders/myfolders/PumpkinRed.png";
symbolimage name=symPBG image="/folders/myfolders/PumpkinOrange.png";
styleattrs datasymbols=(symPBG symPLD symPLR symPSD symPSR);
xaxis display=none; yaxis display=none;
title height=16pt bold "2016 Electoral Map (Source: CNN, 10-22-2016)";
scatter x=column y=row / group=prediction markerattrs=(size=47pt) name="SCATTER";
text x=column y=row text=statecode / position=top textattrs=(color=black size=9.5pt weight=bold);
keylegend "SCATTER" / valueattrs=(size=11) autoitemsize;

 

TRANSPARENT .PNG IMAGES (COLORIZED MS-OFFICE CLIPART, REDUCED SIZE FROM ORIGINALS)

PumpkinRed.pngPumpkinLightRed.pngPumpkinBlue.pngPumpkinLIghtBLue.pngPumpkinOrange.png 

Jay54
Meteorite | Level 14

Cool!  Though I liked the icon sizes in the legend of your previous plot.  

 

I am concerned about the small size of the icons in the legend.  I see you are using AutoItemSize.  They could get bigger if you make the value font in the legend bigger.  But I am not sure if there is any other ways to scale up just the legend symbols.  I will check.

sas-innovate-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

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