<?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 Fun With SAS ODS Graphics: &amp;quot;Bublé Sort&amp;quot; in Graphics Programming</title>
    <link>https://communities.sas.com/t5/Graphics-Programming/Fun-With-SAS-ODS-Graphics-quot-Bubl%C3%A9-Sort-quot/m-p/286659#M10154</link>
    <description>&lt;P&gt;&lt;IMG title="BubleBubbleSort.gif" alt="BubleBubbleSort.gif" src="https://communities.sas.com/t5/image/serverpage/image-id/4198iE699E326AD05A090/image-size/original?v=v2&amp;amp;px=-1" border="0" /&gt;&lt;/P&gt;
&lt;DIV&gt;Donald Knuth's &lt;A href="https://www.amazon.com/Art-Computer-Programming-Sorting-Searching/dp/0201896850" target="_self"&gt;The Art of Computer Programming: Volume 3: Sorting and Searching&lt;/A&gt; is amazing and all, but I must confess that the day I was introduced to SYNCSORT was pretty much the last day I gave a thought to the details of sorting algorithms.&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;But then &lt;A href="https://twitter.com/HomesAtMetacoda" target="_self"&gt;@HomesAtMetacoda&lt;/A&gt; had to go and tweet out this &lt;A href="https://twitter.com/HomesAtMetacoda/status/756109091039219712" target="_self"&gt;nifty visualization of 8 fundamental sorting algorithms&lt;/A&gt;.&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;And before you know it, I was using (abusing?) SAS ODS Graphics to&amp;nbsp;come up with&amp;nbsp;"Bublé Sort" (code below, apologies for the bad pun!), an animated GIF that attempts to illustrate how a simple &lt;A href="https://en.wikipedia.org/wiki/Bubble_sort" target="_self"&gt;Bubble Sort&lt;/A&gt; works by showing how its paired comparisons put unsorted song track listings from Michael Bublé's &lt;A href="http://www.michaelbuble.com/album/let-it-snow-ep" target="_self"&gt;&lt;EM&gt;Let it Snow&lt;/EM&gt;&lt;/A&gt; EP back into their proper order.&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;Oh well, enough sorting nostalgia - back to PROC SORT and SQL ORDERED BY on Monday!&lt;/DIV&gt;
&lt;DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;* Animated bubble sort of tracks from Michael Bublé's Let It Snow EP;

data LetItSnow;                             * Read unsorted EP tracks;       
input Song $char50.;
cards;
5 White Christmas
3 Grown-Up Christmas
1 Let It Snow
6 Let It Snow (Live)
2 The Christmas Song
4 I'll Be Home For Christmas
;
proc sql noprint;                           * How many rows to sort?;
select count(*) into :n from LetItSnow;

data ChartData;                             * Read songs into array and bubble sort;
array songs(&amp;amp;n) $ 50. _temporary_;          * Generate frames at key points for animated GIF;
set LetItSnow end=eof;
songs(_n_)=song;
if eof;
do d=1 to 5;                       
  link GenerateFrame;                       * Frames at start of sort;
end;
do i=1 to &amp;amp;n;                               * Bubble sort: en.wikipedia.org/wiki/Bubble_sort;
  do j=2 to &amp;amp;n-i+1;
    adjY=0;
     do d=1 to 2;
       link GenerateFrame;                  * Frames of current comparison (beginning);
    end;
    if songs(j)&amp;lt;songs(j-1) then do;         * Swap elements, generate swap frames; 
       adjY=.3333;                          * Move 1/3rd of way to destination;
       link GenerateFrame;
       adjY=.6666;                          * Move 2/3rd of way to destination;
       link GenerateFrame;
       adjY=0;
       temp=songs(j-1);
       songs(j-1)=songs(j);
       songs(j)=temp;
       end;
     do d=1 to 2;
       link GenerateFrame;                  * Frames of current comparison (ending);
     end;
  end;       
end;

j=.;   
do d=1 to 7;
  link GenerateFrame;                       * Frames at end of sort;
end;
stop;

GenerateFrame:
chartnum+1;                                 * Generate frame data for animated GIF;
do k=1 to &amp;amp;n;
  if j-1=k then r=k-.4;                     * Reference lines hightlight value being compared;
  else if j=k then r=k+.4;
  else r=.;
  if j-1&amp;lt;=k&amp;lt;=j then color=1; else color=0;  * Color also used to highlight compared values;
  x=0;
  y=k;
  if j-1=k then y+adjY;                     * Adjust y-values of swapped elements;
  if j=k then y+(-adjY);
  song=songs(k);
  invisibleY=-10;                           * Off-plot y-value, used for "blank" EP image frame;
  output;
end;
return; 
run;

ods _all_ close;                            * Use generated data to produce animated GIF;
options papersize=('5 in', '5 in') printerpath=gif animation=start 
        nodate nonumber animduration=.25 animloop=YES NOANIMOVERLAY;
ods printer file='/folders/myfolders/sort/BubleBubbleSort.gif';
ods graphics / border=off width=5in height=5in imagefmt=GIF;
title  height=18pt """Bublé Sort""";
title2 height=12pt "Bubble Sorting Tracks From Michael Bublé's " italic "Let It Snow" ;
title3 " ";
                                            * Image of Let It Snow EP; 
data EP;                                    * Credit: michaelbuble.com/album/let-it-snow-ep;
function='image'; Image="/folders/myfolders/LetItSnow.gif"; layer='front';

option nobyline;                            * Generate 5 leader frames with EP image;
proc sgplot data=ChartData(where=(chartnum&amp;lt;=5)) noautolegend sganno=ep;
by chartnum;
text x=x y=invisibleY text=song;
yaxis reverse min=0 max=%eval(&amp;amp;n+1) display=none;
xaxis display=none;

proc sgplot data=ChartData noautolegend;    * Generate frames from bubble sort data;
by chartnum;
text x=x y=y text=song / textattrs=(size=22pt) colorresponse=color colormodel=(green green red);
yaxis reverse min=0 max=%eval(&amp;amp;n+1) display=none;
xaxis display=none;
refline r / axis=y;
run;

options printerpath=gif animation=stop;     * Wrap it up;
ods printer close;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
    <pubDate>Sun, 24 Jul 2016 13:51:28 GMT</pubDate>
    <dc:creator>tc</dc:creator>
    <dc:date>2016-07-24T13:51:28Z</dc:date>
    <item>
      <title>Fun With SAS ODS Graphics: "Bublé Sort"</title>
      <link>https://communities.sas.com/t5/Graphics-Programming/Fun-With-SAS-ODS-Graphics-quot-Bubl%C3%A9-Sort-quot/m-p/286659#M10154</link>
      <description>&lt;P&gt;&lt;IMG title="BubleBubbleSort.gif" alt="BubleBubbleSort.gif" src="https://communities.sas.com/t5/image/serverpage/image-id/4198iE699E326AD05A090/image-size/original?v=v2&amp;amp;px=-1" border="0" /&gt;&lt;/P&gt;
&lt;DIV&gt;Donald Knuth's &lt;A href="https://www.amazon.com/Art-Computer-Programming-Sorting-Searching/dp/0201896850" target="_self"&gt;The Art of Computer Programming: Volume 3: Sorting and Searching&lt;/A&gt; is amazing and all, but I must confess that the day I was introduced to SYNCSORT was pretty much the last day I gave a thought to the details of sorting algorithms.&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;But then &lt;A href="https://twitter.com/HomesAtMetacoda" target="_self"&gt;@HomesAtMetacoda&lt;/A&gt; had to go and tweet out this &lt;A href="https://twitter.com/HomesAtMetacoda/status/756109091039219712" target="_self"&gt;nifty visualization of 8 fundamental sorting algorithms&lt;/A&gt;.&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;And before you know it, I was using (abusing?) SAS ODS Graphics to&amp;nbsp;come up with&amp;nbsp;"Bublé Sort" (code below, apologies for the bad pun!), an animated GIF that attempts to illustrate how a simple &lt;A href="https://en.wikipedia.org/wiki/Bubble_sort" target="_self"&gt;Bubble Sort&lt;/A&gt; works by showing how its paired comparisons put unsorted song track listings from Michael Bublé's &lt;A href="http://www.michaelbuble.com/album/let-it-snow-ep" target="_self"&gt;&lt;EM&gt;Let it Snow&lt;/EM&gt;&lt;/A&gt; EP back into their proper order.&lt;/DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;Oh well, enough sorting nostalgia - back to PROC SORT and SQL ORDERED BY on Monday!&lt;/DIV&gt;
&lt;DIV&gt;
&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;* Animated bubble sort of tracks from Michael Bublé's Let It Snow EP;

data LetItSnow;                             * Read unsorted EP tracks;       
input Song $char50.;
cards;
5 White Christmas
3 Grown-Up Christmas
1 Let It Snow
6 Let It Snow (Live)
2 The Christmas Song
4 I'll Be Home For Christmas
;
proc sql noprint;                           * How many rows to sort?;
select count(*) into :n from LetItSnow;

data ChartData;                             * Read songs into array and bubble sort;
array songs(&amp;amp;n) $ 50. _temporary_;          * Generate frames at key points for animated GIF;
set LetItSnow end=eof;
songs(_n_)=song;
if eof;
do d=1 to 5;                       
  link GenerateFrame;                       * Frames at start of sort;
end;
do i=1 to &amp;amp;n;                               * Bubble sort: en.wikipedia.org/wiki/Bubble_sort;
  do j=2 to &amp;amp;n-i+1;
    adjY=0;
     do d=1 to 2;
       link GenerateFrame;                  * Frames of current comparison (beginning);
    end;
    if songs(j)&amp;lt;songs(j-1) then do;         * Swap elements, generate swap frames; 
       adjY=.3333;                          * Move 1/3rd of way to destination;
       link GenerateFrame;
       adjY=.6666;                          * Move 2/3rd of way to destination;
       link GenerateFrame;
       adjY=0;
       temp=songs(j-1);
       songs(j-1)=songs(j);
       songs(j)=temp;
       end;
     do d=1 to 2;
       link GenerateFrame;                  * Frames of current comparison (ending);
     end;
  end;       
end;

j=.;   
do d=1 to 7;
  link GenerateFrame;                       * Frames at end of sort;
end;
stop;

GenerateFrame:
chartnum+1;                                 * Generate frame data for animated GIF;
do k=1 to &amp;amp;n;
  if j-1=k then r=k-.4;                     * Reference lines hightlight value being compared;
  else if j=k then r=k+.4;
  else r=.;
  if j-1&amp;lt;=k&amp;lt;=j then color=1; else color=0;  * Color also used to highlight compared values;
  x=0;
  y=k;
  if j-1=k then y+adjY;                     * Adjust y-values of swapped elements;
  if j=k then y+(-adjY);
  song=songs(k);
  invisibleY=-10;                           * Off-plot y-value, used for "blank" EP image frame;
  output;
end;
return; 
run;

ods _all_ close;                            * Use generated data to produce animated GIF;
options papersize=('5 in', '5 in') printerpath=gif animation=start 
        nodate nonumber animduration=.25 animloop=YES NOANIMOVERLAY;
ods printer file='/folders/myfolders/sort/BubleBubbleSort.gif';
ods graphics / border=off width=5in height=5in imagefmt=GIF;
title  height=18pt """Bublé Sort""";
title2 height=12pt "Bubble Sorting Tracks From Michael Bublé's " italic "Let It Snow" ;
title3 " ";
                                            * Image of Let It Snow EP; 
data EP;                                    * Credit: michaelbuble.com/album/let-it-snow-ep;
function='image'; Image="/folders/myfolders/LetItSnow.gif"; layer='front';

option nobyline;                            * Generate 5 leader frames with EP image;
proc sgplot data=ChartData(where=(chartnum&amp;lt;=5)) noautolegend sganno=ep;
by chartnum;
text x=x y=invisibleY text=song;
yaxis reverse min=0 max=%eval(&amp;amp;n+1) display=none;
xaxis display=none;

proc sgplot data=ChartData noautolegend;    * Generate frames from bubble sort data;
by chartnum;
text x=x y=y text=song / textattrs=(size=22pt) colorresponse=color colormodel=(green green red);
yaxis reverse min=0 max=%eval(&amp;amp;n+1) display=none;
xaxis display=none;
refline r / axis=y;
run;

options printerpath=gif animation=stop;     * Wrap it up;
ods printer close;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;/DIV&gt;
&lt;/DIV&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Sun, 24 Jul 2016 13:51:28 GMT</pubDate>
      <guid>https://communities.sas.com/t5/Graphics-Programming/Fun-With-SAS-ODS-Graphics-quot-Bubl%C3%A9-Sort-quot/m-p/286659#M10154</guid>
      <dc:creator>tc</dc:creator>
      <dc:date>2016-07-24T13:51:28Z</dc:date>
    </item>
    <item>
      <title>Re: Fun With SAS ODS Graphics: "Bublé Sort"</title>
      <link>https://communities.sas.com/t5/Graphics-Programming/Fun-With-SAS-ODS-Graphics-quot-Bubl%C3%A9-Sort-quot/m-p/286667#M10155</link>
      <description>&lt;P&gt;Very interesting visual implementation of the "Bubble Sort" algorithm using TEXT plot statement.&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Sun, 24 Jul 2016 15:33:05 GMT</pubDate>
      <guid>https://communities.sas.com/t5/Graphics-Programming/Fun-With-SAS-ODS-Graphics-quot-Bubl%C3%A9-Sort-quot/m-p/286667#M10155</guid>
      <dc:creator>Jay54</dc:creator>
      <dc:date>2016-07-24T15:33:05Z</dc:date>
    </item>
    <item>
      <title>Re: Fun With SAS ODS Graphics: "Bublé Sort"</title>
      <link>https://communities.sas.com/t5/Graphics-Programming/Fun-With-SAS-ODS-Graphics-quot-Bubl%C3%A9-Sort-quot/m-p/286712#M10156</link>
      <description>&lt;P&gt;Impressive&amp;nbsp;Bublé Bubble sort - I prefer your SASsy sort! (Love the pun too)&amp;nbsp;&lt;img id="smileyhappy" class="emoticon emoticon-smileyhappy" src="https://communities.sas.com/i/smilies/16x16_smiley-happy.png" alt="Smiley Happy" title="Smiley Happy" /&gt;&lt;/P&gt;</description>
      <pubDate>Sun, 24 Jul 2016 21:27:13 GMT</pubDate>
      <guid>https://communities.sas.com/t5/Graphics-Programming/Fun-With-SAS-ODS-Graphics-quot-Bubl%C3%A9-Sort-quot/m-p/286712#M10156</guid>
      <dc:creator>MichelleHomes</dc:creator>
      <dc:date>2016-07-24T21:27:13Z</dc:date>
    </item>
    <item>
      <title>Re: Fun With SAS ODS Graphics: "Bublé Sort"</title>
      <link>https://communities.sas.com/t5/Graphics-Programming/Fun-With-SAS-ODS-Graphics-quot-Bubl%C3%A9-Sort-quot/m-p/286713#M10157</link>
      <description>Very neat</description>
      <pubDate>Sun, 24 Jul 2016 21:35:56 GMT</pubDate>
      <guid>https://communities.sas.com/t5/Graphics-Programming/Fun-With-SAS-ODS-Graphics-quot-Bubl%C3%A9-Sort-quot/m-p/286713#M10157</guid>
      <dc:creator>rogerjdeangelis</dc:creator>
      <dc:date>2016-07-24T21:35:56Z</dc:date>
    </item>
  </channel>
</rss>

