<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Creating A New York Times-Like Tile Grid U.S. Map With SAS ODS Graphics in Graphics Programming</title>
    <link>https://communities.sas.com/t5/Graphics-Programming/Creating-A-New-York-Times-Like-Tile-Grid-U-S-Map-With-SAS-ODS/m-p/790814#M22500</link>
    <description>&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="nytpage.png" style="width: 999px;"&gt;&lt;img src="https://communities.sas.com/t5/image/serverpage/image-id/67491i351F091A4E7CD1D7/image-size/large?v=v2&amp;amp;px=999" role="button" title="nytpage.png" alt="nytpage.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Here's a SAS ODS Graphics take on a neat &lt;A href="https://twitter.com/AlbertoCairo/status/1481289889421398026" target="_self"&gt;New York Times tile grid U.S. map that graced nearly a full page of the Jan 12th paper&lt;/A&gt; and was much-liked on Twitter. No details, unfortunately, on what the talented NYT folks used to prep the data, generate the chart and add the text, so I took a crack at the whole soup-to-nuts process with SAS code.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Note:&lt;/STRONG&gt; To view a larger image, right-click above image and select &lt;STRONG&gt;&lt;EM&gt;Open image in new tab&lt;/EM&gt;&lt;/STRONG&gt;. To view a full-resolution image, visit &lt;A href="https://twitter.com/vivasasvegas/status/1483804744359591942" target="_self"&gt;Twitter post&lt;/A&gt;, click on thumbnail, then right-click next image and select &lt;EM&gt;&lt;STRONG&gt;Open image in new tab&lt;/STRONG&gt;.&lt;/EM&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;* Creating A New York Times-Like Tile Grid U.S. Map With SAS ODS Graphics
  Attempt to knockoff full-page graphic in 1-12-2022 NYT - see twitter.com/AlbertoCairo/status/1481289889421398026;
 
data NytMap;                                        * Generate coordinates for NYT tile map of U.S.; 
do r=1 to 8;                                        * Eight rows;
  input; 
  do c=1 to 11;                                     * Eleven columns;
    p=r*100+c;                                      * Assign 4-digit # to 88 cells of panel chart; 
    st=input(substr(_infile_,(c-1)*3+1,2),$2.);     * Grab 2-character state abbreviations;  
    output;  
  end; 
end;
datalines;                                          * NYT tile grid map "template";                                      
                              ME
                           VT NH
WA ID MT ND MN IL WI MI NY RI MA
OR NV WY SD IA IN OH PA NJ CT
CA UT CO NE MO KY WV VA MD DE
   AZ NM KS AR TN NC SC DC
         OK LA MS AL GA
AK HI    TX             FL
;                                                 * Read NYT COVID-19 state-level daily data;
filename nytdata url 'https://raw.githubusercontent.com/nytimes/covid-19-data/master/rolling-averages/us-states.csv'; 
proc import out=NYTdata(where=(date&amp;lt;='10jan2022'd)) file=nytdata dbms=csv replace; * NYT chart we're trying to replicate was thru Jan 10;

proc sql;                                         * Merge COVID-19 data with map coordinates and derive several fields;
create table NytDataMap as
select d.st, d.state, d.date, d.cases_avg_per_100k, m.p, md.maxdate,
       case when date=md.maxdate then d.cases_avg_per_100k end as EndingCases,
       case when date=md.maxdate then put(d.cases_avg_per_100k, 4.) end as EndingCasesX,
       case when pcm.prevMonthsMaxCases&amp;lt;currMonthMaxCases then 'Record Cases in January' else 'Cases Rising' end as color
from NytMap m 
left join (select fipstate(input(scan(geoid,2),2.)) as st, state, date, cases_avg_per_100k from nytdata) d on d.st=m.st
left join (select state, max(date) as maxdate from nytdata group by 1) md on d.state=md.state
left join (select state, max(case when date &amp;lt; '01jan2022'd then cases_avg_per_100k end) as prevMonthsMaxCases,
                         max(case when date between '01jan2022'd and '31jan2022'd then cases_avg_per_100k end) as currMonthMaxCases
           from nytdata group by 1) pcm on pcm.state=d.state
order by m.p, d.st, d.date;

data years;                                       * Show years the data covers (but only on WA cells);
st='WA'; p=3*100+1; yrY=.; 
do yrX='01jan2020'd, '01jan2021'd, '01jan2022'd; 
  yr="'"||substr(put(yrX,year4.),3); 
  output; 
end;

data NytDataMapYears; set nytdatamap years;       * Merge the NYT data and the year annotations;    
proc sort data=nytdatamapyears; by p st date;

data attrmap;                                     * Create an attribute to assign colors based on cases in January; 
ID="id"; value="Record Cases in January"; markercolor="red "; linecolor="red "; output;
ID="id"; value="Cases Rising           "; markercolor="gray"; linecolor="gray"; output;

*==&amp;gt; Use PROC SGPANEL with series and scatter plots to create the U.S. tile map;

ods listing image_dpi=200 gpath='/home/ted.conway/';
ods graphics / border=off reset antialias height=8.5in width=11in imagename="nytmap" antialiasmax=35000;
proc sgpanel data=nytdatamapyears(where=(p^=.)) noautolegend subpixel dattrmap=attrmap;
panelby p / start=topleft sort=(ascending descending) noborder novarname nowall columns=11 rows=9 missing noheader onepanel;
inset st / nolabel position=topleft textattrs=(color=black size=9.5pt weight=bold); * Show 2-digit state codes in insets;
series x=date y=cases_avg_per_100k / group=color attrid=id smoothconnect lineattrs=(pattern=solid thickness=1.5pt); * Show cases by day trend lines;
scatter x=date y=EndingCases / labelstrip datalabel datalabelattrs=(color=black weight=bold) datalabelpos=top markerattrs=(symbol=circlefilled size=11pt color=white) markeroutlineattrs=(color=white); * Create marker separated from line for ending date;  
scatter x=date y=EndingCases / group=color attrid=id markerattrs=(symbol=circlefilled) markeroutlineattrs=(color=white);
refline yrx / axis=x label=yr labelpos=min labelattrs=(color=black size=7pt weight=bold) transparency=.8 lineattrs=(color=black pattern=shortdash thickness=1.5pt); * Reference lines showing years (WA only);
colaxis display=none offsetmin=0 offsetmax=0;
rowaxis display=none offsetmin=0;
format EndingCases 4.;

*==&amp;gt; Use GTL to overlay text atop tile map image (one might just do this instead with editing software!);
                                                   
data dummy;                                        * Need "dummy" data for plot (one point); 
retain x y .5;

proc template;                                     * Specify text to overlay on map background image;
define statgraph image;                            
begingraph / subpixel=on border=false opaque=false;
layout overlay / xaxisopts=(display=none) yaxisopts=(display=none) walldisplay=none pad=0 outerpad=(top=0pt bottom=0pt left=0pt right=0pt);
scatterplot x=x y=y / markerattrs=(size=0);        * Dummy scatter plot (invisible marker);
                                                   * Set background to U.S. tile map created in prior step;
drawimage "/home/ted.conway/nytmap.png" / border=false height=100 layer=back heightunit=percent drawspace=graphpercent;
                                                   * Put headings + narrative + legend in space at top left of map image;
Layout Gridded / rows=10 order=columnmajor border=false autoalign=(topleft) pad=0 outerpad=0;
entry halign=left textattrs=(size=19pt weight=bold) "What to Make of Those Soaring Covid Counts " / pad=0 outerpad=0 ;
entry halign=left textattrs=(size=9pt weight=bold style=italic) halign=left "Note:" textattrs=(size=9pt style=italic weight=normal) " This is a knockoff of a 1-12-2022 New York Times graphic  " / pad=0 outerpad=0 ;
entry halign=left textattrs=(size=8.5pt) "Coronavirus case counts have reached record highs in the United States and continue to climb. Hospitalizations have surpassed last winter's  " / pad=0 outerpad=0 ; 
entry halign=left textattrs=(size=8.5pt) "wave. Deaths are also beginning to rise. The overall pattern is familiar, but a fresh perspective on how to interpret these metrics may be  " / pad=0 outerpad=0; 
entry halign=left textattrs=(size=8.5pt) "necessary as a faster but less severe variant tears through the country. Here's how to interpret the data in the coming days and weeks.  " / pad=0 outerpad=0 ; 
entry halign=left " " / pad=0 outerpad=0;
entry halign=left textattrs=(size=13pt weight=bold) "Average daily cases per 100,000 people  " / pad=0 outerpad=0 ; 
entry halign=left textattrs=(size=16pt color=red) {unicode '25cf'x} textattrs=(size=11pt color=black) " Record cases in January   " textattrs=(size=16pt color=gray) {unicode '25cf'x} textattrs=(size=11pt color=black) " Cases rising  " / pad=0 outerpad=0 ; 
Endlayout;
                                                     * Put notes in space at bottom right of map image;
Layout Gridded / rows=5 order=columnmajor border=false autoalign=(bottomright) pad=0 outerpad=0;
entry halign=left textattrs=(size=7.5pt) "  Note: All figures are 7-day " / pad=0 outerpad=0 ;
entry halign=left textattrs=(size=7.5pt) "  rolling averages as of Jan 10. " / pad=0 outerpad=0 ;
entry halign=left textattrs=(size=7.5pt) "  Source: New York Times  " / pad=0 outerpad=0 ;
entry halign=left textattrs=(size=7.5pt) "  database of reports from state " / pad=0 outerpad=0 ;
entry halign=left textattrs=(size=7.5pt) "  and local health agencies. " / pad=0 outerpad=0 ;
Endlayout;
endlayout;
endgraph;
end;
run; 
                                                      * Create the full map + text image!; 
ods listing image_dpi=200 gpath='/home/ted.conway/';
ods graphics on / reset antialias width=11in height=8.5in imagename="nytpage" border=off;
proc sgrender data=dummy template=image;
run;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Knockoff v. Original" style="width: 999px;"&gt;&lt;img src="https://communities.sas.com/t5/image/serverpage/image-id/67492i98E1388DA21563F0/image-size/large?v=v2&amp;amp;px=999" role="button" title="nytcompare.JPG" alt="Knockoff v. Original" /&gt;&lt;span class="lia-inline-image-caption" onclick="event.preventDefault();"&gt;Knockoff v. Original&lt;/span&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
    <pubDate>Wed, 19 Jan 2022 14:19:07 GMT</pubDate>
    <dc:creator>tc</dc:creator>
    <dc:date>2022-01-19T14:19:07Z</dc:date>
    <item>
      <title>Creating A New York Times-Like Tile Grid U.S. Map With SAS ODS Graphics</title>
      <link>https://communities.sas.com/t5/Graphics-Programming/Creating-A-New-York-Times-Like-Tile-Grid-U-S-Map-With-SAS-ODS/m-p/790814#M22500</link>
      <description>&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="nytpage.png" style="width: 999px;"&gt;&lt;img src="https://communities.sas.com/t5/image/serverpage/image-id/67491i351F091A4E7CD1D7/image-size/large?v=v2&amp;amp;px=999" role="button" title="nytpage.png" alt="nytpage.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Here's a SAS ODS Graphics take on a neat &lt;A href="https://twitter.com/AlbertoCairo/status/1481289889421398026" target="_self"&gt;New York Times tile grid U.S. map that graced nearly a full page of the Jan 12th paper&lt;/A&gt; and was much-liked on Twitter. No details, unfortunately, on what the talented NYT folks used to prep the data, generate the chart and add the text, so I took a crack at the whole soup-to-nuts process with SAS code.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Note:&lt;/STRONG&gt; To view a larger image, right-click above image and select &lt;STRONG&gt;&lt;EM&gt;Open image in new tab&lt;/EM&gt;&lt;/STRONG&gt;. To view a full-resolution image, visit &lt;A href="https://twitter.com/vivasasvegas/status/1483804744359591942" target="_self"&gt;Twitter post&lt;/A&gt;, click on thumbnail, then right-click next image and select &lt;EM&gt;&lt;STRONG&gt;Open image in new tab&lt;/STRONG&gt;.&lt;/EM&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;* Creating A New York Times-Like Tile Grid U.S. Map With SAS ODS Graphics
  Attempt to knockoff full-page graphic in 1-12-2022 NYT - see twitter.com/AlbertoCairo/status/1481289889421398026;
 
data NytMap;                                        * Generate coordinates for NYT tile map of U.S.; 
do r=1 to 8;                                        * Eight rows;
  input; 
  do c=1 to 11;                                     * Eleven columns;
    p=r*100+c;                                      * Assign 4-digit # to 88 cells of panel chart; 
    st=input(substr(_infile_,(c-1)*3+1,2),$2.);     * Grab 2-character state abbreviations;  
    output;  
  end; 
end;
datalines;                                          * NYT tile grid map "template";                                      
                              ME
                           VT NH
WA ID MT ND MN IL WI MI NY RI MA
OR NV WY SD IA IN OH PA NJ CT
CA UT CO NE MO KY WV VA MD DE
   AZ NM KS AR TN NC SC DC
         OK LA MS AL GA
AK HI    TX             FL
;                                                 * Read NYT COVID-19 state-level daily data;
filename nytdata url 'https://raw.githubusercontent.com/nytimes/covid-19-data/master/rolling-averages/us-states.csv'; 
proc import out=NYTdata(where=(date&amp;lt;='10jan2022'd)) file=nytdata dbms=csv replace; * NYT chart we're trying to replicate was thru Jan 10;

proc sql;                                         * Merge COVID-19 data with map coordinates and derive several fields;
create table NytDataMap as
select d.st, d.state, d.date, d.cases_avg_per_100k, m.p, md.maxdate,
       case when date=md.maxdate then d.cases_avg_per_100k end as EndingCases,
       case when date=md.maxdate then put(d.cases_avg_per_100k, 4.) end as EndingCasesX,
       case when pcm.prevMonthsMaxCases&amp;lt;currMonthMaxCases then 'Record Cases in January' else 'Cases Rising' end as color
from NytMap m 
left join (select fipstate(input(scan(geoid,2),2.)) as st, state, date, cases_avg_per_100k from nytdata) d on d.st=m.st
left join (select state, max(date) as maxdate from nytdata group by 1) md on d.state=md.state
left join (select state, max(case when date &amp;lt; '01jan2022'd then cases_avg_per_100k end) as prevMonthsMaxCases,
                         max(case when date between '01jan2022'd and '31jan2022'd then cases_avg_per_100k end) as currMonthMaxCases
           from nytdata group by 1) pcm on pcm.state=d.state
order by m.p, d.st, d.date;

data years;                                       * Show years the data covers (but only on WA cells);
st='WA'; p=3*100+1; yrY=.; 
do yrX='01jan2020'd, '01jan2021'd, '01jan2022'd; 
  yr="'"||substr(put(yrX,year4.),3); 
  output; 
end;

data NytDataMapYears; set nytdatamap years;       * Merge the NYT data and the year annotations;    
proc sort data=nytdatamapyears; by p st date;

data attrmap;                                     * Create an attribute to assign colors based on cases in January; 
ID="id"; value="Record Cases in January"; markercolor="red "; linecolor="red "; output;
ID="id"; value="Cases Rising           "; markercolor="gray"; linecolor="gray"; output;

*==&amp;gt; Use PROC SGPANEL with series and scatter plots to create the U.S. tile map;

ods listing image_dpi=200 gpath='/home/ted.conway/';
ods graphics / border=off reset antialias height=8.5in width=11in imagename="nytmap" antialiasmax=35000;
proc sgpanel data=nytdatamapyears(where=(p^=.)) noautolegend subpixel dattrmap=attrmap;
panelby p / start=topleft sort=(ascending descending) noborder novarname nowall columns=11 rows=9 missing noheader onepanel;
inset st / nolabel position=topleft textattrs=(color=black size=9.5pt weight=bold); * Show 2-digit state codes in insets;
series x=date y=cases_avg_per_100k / group=color attrid=id smoothconnect lineattrs=(pattern=solid thickness=1.5pt); * Show cases by day trend lines;
scatter x=date y=EndingCases / labelstrip datalabel datalabelattrs=(color=black weight=bold) datalabelpos=top markerattrs=(symbol=circlefilled size=11pt color=white) markeroutlineattrs=(color=white); * Create marker separated from line for ending date;  
scatter x=date y=EndingCases / group=color attrid=id markerattrs=(symbol=circlefilled) markeroutlineattrs=(color=white);
refline yrx / axis=x label=yr labelpos=min labelattrs=(color=black size=7pt weight=bold) transparency=.8 lineattrs=(color=black pattern=shortdash thickness=1.5pt); * Reference lines showing years (WA only);
colaxis display=none offsetmin=0 offsetmax=0;
rowaxis display=none offsetmin=0;
format EndingCases 4.;

*==&amp;gt; Use GTL to overlay text atop tile map image (one might just do this instead with editing software!);
                                                   
data dummy;                                        * Need "dummy" data for plot (one point); 
retain x y .5;

proc template;                                     * Specify text to overlay on map background image;
define statgraph image;                            
begingraph / subpixel=on border=false opaque=false;
layout overlay / xaxisopts=(display=none) yaxisopts=(display=none) walldisplay=none pad=0 outerpad=(top=0pt bottom=0pt left=0pt right=0pt);
scatterplot x=x y=y / markerattrs=(size=0);        * Dummy scatter plot (invisible marker);
                                                   * Set background to U.S. tile map created in prior step;
drawimage "/home/ted.conway/nytmap.png" / border=false height=100 layer=back heightunit=percent drawspace=graphpercent;
                                                   * Put headings + narrative + legend in space at top left of map image;
Layout Gridded / rows=10 order=columnmajor border=false autoalign=(topleft) pad=0 outerpad=0;
entry halign=left textattrs=(size=19pt weight=bold) "What to Make of Those Soaring Covid Counts " / pad=0 outerpad=0 ;
entry halign=left textattrs=(size=9pt weight=bold style=italic) halign=left "Note:" textattrs=(size=9pt style=italic weight=normal) " This is a knockoff of a 1-12-2022 New York Times graphic  " / pad=0 outerpad=0 ;
entry halign=left textattrs=(size=8.5pt) "Coronavirus case counts have reached record highs in the United States and continue to climb. Hospitalizations have surpassed last winter's  " / pad=0 outerpad=0 ; 
entry halign=left textattrs=(size=8.5pt) "wave. Deaths are also beginning to rise. The overall pattern is familiar, but a fresh perspective on how to interpret these metrics may be  " / pad=0 outerpad=0; 
entry halign=left textattrs=(size=8.5pt) "necessary as a faster but less severe variant tears through the country. Here's how to interpret the data in the coming days and weeks.  " / pad=0 outerpad=0 ; 
entry halign=left " " / pad=0 outerpad=0;
entry halign=left textattrs=(size=13pt weight=bold) "Average daily cases per 100,000 people  " / pad=0 outerpad=0 ; 
entry halign=left textattrs=(size=16pt color=red) {unicode '25cf'x} textattrs=(size=11pt color=black) " Record cases in January   " textattrs=(size=16pt color=gray) {unicode '25cf'x} textattrs=(size=11pt color=black) " Cases rising  " / pad=0 outerpad=0 ; 
Endlayout;
                                                     * Put notes in space at bottom right of map image;
Layout Gridded / rows=5 order=columnmajor border=false autoalign=(bottomright) pad=0 outerpad=0;
entry halign=left textattrs=(size=7.5pt) "  Note: All figures are 7-day " / pad=0 outerpad=0 ;
entry halign=left textattrs=(size=7.5pt) "  rolling averages as of Jan 10. " / pad=0 outerpad=0 ;
entry halign=left textattrs=(size=7.5pt) "  Source: New York Times  " / pad=0 outerpad=0 ;
entry halign=left textattrs=(size=7.5pt) "  database of reports from state " / pad=0 outerpad=0 ;
entry halign=left textattrs=(size=7.5pt) "  and local health agencies. " / pad=0 outerpad=0 ;
Endlayout;
endlayout;
endgraph;
end;
run; 
                                                      * Create the full map + text image!; 
ods listing image_dpi=200 gpath='/home/ted.conway/';
ods graphics on / reset antialias width=11in height=8.5in imagename="nytpage" border=off;
proc sgrender data=dummy template=image;
run;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Knockoff v. Original" style="width: 999px;"&gt;&lt;img src="https://communities.sas.com/t5/image/serverpage/image-id/67492i98E1388DA21563F0/image-size/large?v=v2&amp;amp;px=999" role="button" title="nytcompare.JPG" alt="Knockoff v. Original" /&gt;&lt;span class="lia-inline-image-caption" onclick="event.preventDefault();"&gt;Knockoff v. Original&lt;/span&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Wed, 19 Jan 2022 14:19:07 GMT</pubDate>
      <guid>https://communities.sas.com/t5/Graphics-Programming/Creating-A-New-York-Times-Like-Tile-Grid-U-S-Map-With-SAS-ODS/m-p/790814#M22500</guid>
      <dc:creator>tc</dc:creator>
      <dc:date>2022-01-19T14:19:07Z</dc:date>
    </item>
    <item>
      <title>Re: Creating A New York Times-Like Tile Grid U.S. Map With SAS ODS Graphics</title>
      <link>https://communities.sas.com/t5/Graphics-Programming/Creating-A-New-York-Times-Like-Tile-Grid-U-S-Map-With-SAS-ODS/m-p/791060#M22501</link>
      <description>&lt;P&gt;Although I don't really like this kind of map, good job with the imitation (and subtle improvements) &lt;span class="lia-unicode-emoji" title=":slightly_smiling_face:"&gt;🙂&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Thu, 20 Jan 2022 00:54:26 GMT</pubDate>
      <guid>https://communities.sas.com/t5/Graphics-Programming/Creating-A-New-York-Times-Like-Tile-Grid-U-S-Map-With-SAS-ODS/m-p/791060#M22501</guid>
      <dc:creator>GraphGuy</dc:creator>
      <dc:date>2022-01-20T00:54:26Z</dc:date>
    </item>
  </channel>
</rss>

