******************************************************************************** * Description of the Program - * * This program is used to preview combinations of color palettes along with * * combinations created by different numbers of colors. * * * * Lines - * * 461 * * * ******************************************************************************** *! brewviewer *! v 1.0.0 *! 21MAR2016 // Drop program if already loaded in memory cap prog drop brewviewer // Define new program brewviewer prog def brewviewer // Interpret syntax under Version 13.1 version 13.1 // Syntax structure for the program syntax anything(name=pal id="BrewScheme Color Palette") /// [, Colors(numlist min = 1 max = 24 integer) COMBine Seq IMpaired ] // Check colors argument if "`colors'" == "" { // Print error message to the console di as err "Must supply at least a single value for the colors parameter." // Error out err 198 } // End IF Block for invalid number of color arguments // Check impairment option to add subtitle to graph if `"`impaired'"' != "" loc xtralab `""with simulated total, red, green, and blue colorblindness""' // Preserve the current state of the data preserve // Load the brewscheme dataset qui: use `"`c(sysdir_personal)'b/brewmeta.dta"', clear // For single color listed if `: word count `colors'' == 1 { // Get maximum number of colors loc maxcol `= `colors'' // If sequence switch is enabled if "`seq'" != "" { // Set color loop syntax loc colloop forv i = 3/`colors' // Get minimum number of colors loc mincol 3 // sets of xaxis values loc simvals `= ((`colors' - 3) + 1)' } // End IF Block for sequence loop // If sequence switch is not enabled else { // Set color loop syntax loc colloop foreach i in `colors' // Get minimum number of colors loc mincol `colors' // Sets of xaxis values loc simvals = 1 } // End ELSE Block for color loop syntax } // End ELSEIF Block for single color value // For fewer colors than palettes else if `: word count `colors'' < `: word count `pal'' { // Get maximum number of colors loc maxcol `= `: di max(`: subinstr loc colors `" "' `", "', all')'' // If sequence switch is enabled if "`seq'" != "" { // Set color loop syntax loc colloop forv i = 3/`maxcol' // Get minimum number of colors loc mincol 3 // sets of xaxis values loc simvals `= ((`maxcol' - 3) + 1)' } // End IF Block for sequence loop // If sequence switch is not enabled else { // Set color loop syntax loc colloop foreach i in `colors' // Get minimum number of colors loc mincol `: di min(`: subinstr loc colors `" "' `", "', all')' // Sets of xaxis values loc simvals = 1 } // End ELSE Block for color loop syntax } // End ELSEIF Block for fewer colors than palettes // If there are more colors than palettes { else if `: word count `colors'' == `: word count `pal'' { // If sequence switch is enabled if "`seq'" != "" { // Set color loop syntax loc colloop forv i = 3/\`: word \`w' of `colors'' // Get minimum number of colors loc mincol 3 } // End IF Block for sequence loop // If sequence switch is not enabled else { // Set color loop syntax loc colloop foreach i in \`: word \`w' of \`colors'' // Get minimum number of colors loc mincol `: di min(`: subinstr loc colors `" "' `", "', all')' } // End ELSE Block for color loop syntax // Get maximum number of colors loc maxcol `= `: di max(`: subinstr loc colors `" "' `", "', all')'' // sets of xaxis values loc simvals `= ((`maxcol' - 3) + 1)' } // End ELSEIF Block for more colors than palettes // If there are more colors than palettes else { // Set color loop syntax loc colloop foreach i in `colors' // Get maximum number of colors loc maxcol `= `: di max(`: subinstr loc colors `" "' `", "', all')'' // Get minimum number of colors loc mincol `: di min(`: subinstr loc colors `" "' `", "', all')' // sets of xaxis values loc simvals `= ((`maxcol' - 3) + 1)' } // End ELSE Block for more colors than palettes // Create counter for simulated values loc simcount = 1 // Loop over the number of palettes passed to the main argument forv w = 1/`: word count `pal'' { // Get the palette name loc palnm : word `w' of `pal' // Get the mean from the maxcolors variable (constant by palette) qui: su maxcolors if palette == `"`palnm'"' // Set a local for maximum number of colors loc bkupmax `r(max)' // Check for colorblindness simulation option if `"`simcb'"' != "" loc sze `= 1.5 + `= 1/(`maxcol' * 5)'' // Set the size of the boxes based on the log of 3 times n colors else loc sze `= 2 + `= 1/`maxcol''' // Local to build xaxis labeling rules loc xax // Initialize scatteri local macro loc cmd // Loop over the smallest number of colors available in any palettes `colloop' { // Find max colors qui: su maxcolors if palette == `"`palnm'"', meanonly // Create graph if acceptable value if `r(mean)' >= `i' { // Initialize a null macro to use like a StringBuilder class in Java loc scat`i' // Loop over the number of unique colors based on the palette color id forv j = 1/`i' { // Get the number of palette color ids qui: levelsof pcolor if palette == `"`palnm'"', loc(pcid) // Test if the value exists in the pcolor ids loc gmax : list i in pcid // If not in pcid list if `gmax' == 0 { // Get maximum number of colors loc pcid `bkupmax' } // End IF Block to get maximum color ID // Else { else { // Set the pcid macro loc pcid `i' } // End ELSE Block for cases where the value is in the pcid list // Get the RGB values for the palette with the palette color id i qui: levelsof rgb if pcolor == `pcid' & colorid == `j' /// & palette == `"`palnm'"', loc(xrgb) // Get the individual RGB value for this iteration loc col "`: word 1 of `xrgb''" // If color blind impairment simulation get the RGB values if `"`impaired'"' != "" { // Get simulated colors mata: translateColor(`: subinstr loc col `" "' `", "', all') // Sets the xaxis position for the baseline palette loc basex `= (`simcount' * 5) - 4' // Sets xaxis label for the baseline palette loc baselab `basex' "`i' " // Sets the xaxis position for the achromatopsia transformed palette loc achromx `= (`simcount' * 5) - 3' // Sets the xaxis label for the achromatopsia transformed palette loc achromlab `achromx' " a " // Sets the xaxis position for the protanopia transformed palette loc protanx `= (`simcount' * 5) - 2' // Sets the xaxis label for the protanopia transformed palette loc protanlab `protanx' " p " // Sets the xaxis position for the deuteranopia transformed palette loc deuterx `= (`simcount' * 5) - 1' // Sets the xaxis label for the deuteranopia transformed palette loc deuteranlab `deuterx' " d " // Sets the xaxis position for the tritanopia transformed palette loc tritanx `= (`simcount' * 5) - 0' // Sets the xaxis label for the tritanopia transformed palette loc tritanlab `tritanx' " t " // Build the command for graphing this individual color/label loc scat`i' `scat`i'' /// (scatteri `j' `basex', mc("`col'") mlabc(black) /// /*msize(`sze' `sze')*/ mlc(black) ms(S)) /// (scatteri `j' `achromx', mlc(black) ms(S) /// mc("`achromatopsia'") /*msize(`sze' `sze')*/) /// (scatteri `j' `protanx', ms(S) mlc(black) /// mc("`protanopia'") /*msize(`sze' `sze')*/) /// (scatteri `j' `deuterx', ms(S) mlc(black) /// mc("`deuteranopia'") /*msize(`sze' `sze')*/) /// (scatteri `j' `tritanx', ms(S) mlc(black) /// mc("`tritanopia'") /*msize(`sze' `sze')*/) // Add to existing x-axis label macros loc xax `xax' `baselab' `achromlab' `protanlab' `deuteranlab' `tritanlab' } // End IF Block for impairment simulation // If not else { // Build the command for graphing this individual color/label loc scat`i' `scat`i'' (scatteri `j' `i', mc("`col'") /// mlabc(black) msize(`sze' `sze') mlc(black) ms(S)) } // End ELSE Block for no color impairment simulation } // End Loop over colors within a given palette color id // Add these to a container macro used to build the full graph syntax loc cmd `cmd' `scat`i'' } // End IF Block for acceptable max value // If it is outside the maximum number of colors else { // Don't alter command macro loc scat`i' `scat`i'' } // For cases when the colors value is > max colors // Increment simvalue counter loc simcount = `simcount' + 1 } // End Loop over the number of palette color ids to use // Check for simulation option if `"`impaired'"' != "" { // Adjust label angle and size loc xax `xax', angle(0) // Remove x-axis title to make room for the additional labeling loc xaxti "" } // End IF Block for impairment option // If option not selected else { // Sort the x axis values loc xax : list sort xax // Remove any duplicate values loc xax : list uniq xax loc xax `xax', angle(0) // Set the x-axis title loc xaxti "# Colors" } // End ELSE Block for graph w/o simulated colorblindness option // Get minimum value loc scales r(`= `mincol' - 0.25'(0.5)`= `maxcol' + 0.25') if `"`impaired'"' != "" { loc note1 "a = Achromatopsia p = Protanopia" loc note2 " d = Deuteranopia t = Tritanopia" loc note note(`note1' `note2', size(medsmall) c(black) pos(7)) } // Graph the color palette tw `cmd', ysca(r(1 `maxcol') off) xsca(`scales') xlab(`xax') /// yti("") ylab(none, nogrid) legend(nodraw) `note' /// xti(`"`xaxti'"') graphr(margin(medlarge) fc(white) lc(white) /// ic(white)) plotr(lc(white) fc(white) ic(white)) /// name(`palnm'`color', replace) xsize(17) ysize(11) /// ti("BrewScheme palette: `palnm' colors" `xtralab', /// size(medsmall) span) // Store the name of the graph loc grnames `grnames' `palnm'`color' } // End Loop over palettes // Check combine option and make sure there are multiple palettes if "`combine'" != "" & `: word count `pal'' >= 2 { // If divisible by 5 and not 5 if mod(`: word count `pal'', 5) == 0 & `: word count `pal'' / 5 != 1 { // Set rows as number of palettes divided by 5 loc r rows(`: word count `pal''/5) // Use 5 columns for the images loc c cols(5) } // End IF Block for row/col options // Else if 4 palettes else if `: word count `pal'' / 4 == 1 { // Two rows loc r rows(2) // Two columns loc c cols(2) } // End ELSEIF Block for row/col options // Else if 6 palettes else if `: word count `pal''/6 == 1 { // Two rows of loc r rows(2) // Three columns loc c cols(3) } // End ELSEIF Block for row/col options // Else if # of palettes is divisible by 4 else if mod(`: word count `pal'', 4) == 0 { // Number of rows = palettes / 4 loc r rows(`: word count `pal''/4) // Use 4 columns loc c cols(4) } // End ELSEIF Block for row/col options // Else if number of palettes is divisible by 3 else if mod(`: word count `pal'', 3) == 0 { // Number of Rows = palettes / 3 loc r rows(`: word count `pal''/3) // Use three columns for the display loc c cols(3) } // End ELSEIF Block for row/col options // All other cases else { // Stata default number of rows loc r // Stata default number of columns loc c } // End ELSE Block for other cases // Combine graphs in a single graph image gr combine `grnames', altshrink graphr(ic(white) fc(white) /// lc(white)) plotr(ic(white) fc(white) lc(white)) `r' `c' /// ysize(8.5) xsize(11) } // End IF Block to combine the graphs // Return original state of the data to the user restore // End the program end