Adding a Shiny app to {dehex}


August 27, 2021

Screenshot of the dehex Shiny app. A randomised colour hex code has been generated in the left panel after clicking a big button labelled 'generate' and the right-hand side shows a numbered tabset open at the final, sixth, tab called 'solve', which shows the name of the colour and a sample of it.

Use the {dehex} app to generate a random hex code and learn how to interpret it by eye.


The {dehex} package now contains a Shiny app that you can use to walk through the process of reading a colour hex code, as per David DeSandro’s method.


In the last post I introduced the R package {dehex}. Its purpose is to help me (you?) look at a colour hex code and be able to ‘read’ roughly what colour it is without resorting to a lookup.

A hexagon-shaped logo with the text 'dehex' in the lower right and a bar chart with a single red, green and blue bar that originates in the top left.

I promise this is a hex sticker, but it’s background is white, whoops.

So, the computer-friendly code ‘#C68738’ can be interpreted by your brain as the human-friendly phrase ‘middle washed orange’.

The package only exists because of a mind-melting talk by David DeSandro and his recommendation of the approach due to his colourblindness. I’m also colourblind and would prefer to ‘solve’ a colour than try and guess what it is from a sample.

An apportunity

The {dehex} package uses a number of functions to help you through the steps of DeSandro’s method. It prints things to the R console to help you.1

There’s dh_shorten() to simplify the code to three digits; dh_graph() to make an RGB chart of your shortened hex code; dh_guide() to preview hue, saturation and lightness profiles to match against your shortened hex code; and dh_solve() to provide you with ‘the answer’, along with RGB charts for the nearest hue, saturation and lightness (HSL) profiles.

Output from the dehex package's dh_graph function, which shows a horizontal bar chart in the RStudio console with a dark theme. The columns are labelled R, G, B, S and L and the ends of the RGB columns are labelled H1, H2 and H3. The RGB bars are coloured red, blue and green; S and L are white. Above the plot is the three-digit colour hex code that graph is summarising.

An RGB bar chart printed by {dehex} to the console, with guides for hue, saturation and lightness.

The trouble is that you have to know what order to run these functions. The documentation, README and blog post provide this information, as well as DeSandro’s resources, but it would be ideal to have an option to showcase {dehex} and learn stuff without needing to type any functions yourself.

So, I’ve created a simple Shiny app and made it available as the dh_app() function in {dehex}.2 I consider it ‘in development’ (this absolves me of liability if I say this, yes?).

The app depends on two packages: {shiny} and {bslib}. You’ll have to install these separately to {dehex} by using install.packages(c("shiny", "bslib")) (if you haven’t already installed them on your machine).

These aren’t dependencies3 because you shouldn’t be forced to install them if you have no plans on using the app.4

Aside: what’s fun is I get to make further use of the Shiny app README badge I invented (?) with my {badgr} package, like so:

A badge that says 'shiny' on the left half and 'in package' on the right half.


The app is pretty simple.

There’s a big blue button labelled ‘Generate’. Click it and a random six-digit colour hex code is generated.

A screenshot from the dehex Shiny app. The 'generate' button has been clicked to reveal the colour hex code 2BEE2B.

‘That is the question.’

Your then proceed through the numbered tabs to learn about each step, get some quick bullets of explanation, and then have the option to reveal help via some outputs from functions in the {dehex} package. There’s also a link to the relevant slide of David DeSandro’s talk.

As a beginner, you’ll want to reveal the tips to get maximum help. As you get better, you may not need to reveal them anymore.

The final tab provides the solution. You should have the answer by the time you get to this tab, but it reveals to you the hue, saturation and lightness RGB profiles that best match the generated hex code, along with the answer as a string, and a sample of the colour itself.

The app is purposefully low on interactivity. It’s just a little sidequest that bundles the steps and relevant {dehex} functions, in case you don’t want to run the functions from R itself.5

Originally I was going to just create an app to go on the web for anyone to use, but why would they want to see outputs from {dehex}? I also think that it’s worth reading DeSandro’s blog and watching or reading his talk in the first instance.

As ever, send suggestions, issues and pull requests in the GitHub repo for the package.


Session info
Last rendered: 2023-07-08 19:08:45 BST
R version 4.3.1 (2023-06-16)
Platform: aarch64-apple-darwin20 (64-bit)
Running under: macOS Ventura 13.2.1

Matrix products: default
BLAS:   /Library/Frameworks/R.framework/Versions/4.3-arm64/Resources/lib/libRblas.0.dylib 
LAPACK: /Library/Frameworks/R.framework/Versions/4.3-arm64/Resources/lib/libRlapack.dylib;  LAPACK version 3.11.0

[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8

time zone: Europe/London
tzcode source: internal

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

loaded via a namespace (and not attached):
 [1] htmlwidgets_1.6.2 compiler_4.3.1    fastmap_1.1.1     cli_3.6.1        
 [5] tools_4.3.1       htmltools_0.5.5   rstudioapi_0.14   yaml_2.3.7       
 [9] rmarkdown_2.23    knitr_1.43.1      jsonlite_1.8.7    xfun_0.39        
[13] digest_0.6.31     rlang_1.1.1       evaluate_0.21    


  1. Yes, but the quality of printing Unicode blocks in the app depends on what browser you’re using to view it. On macOS, Firefox seems fine. Other browsers don’t line up the little Unicode blocks nicely when outputting from dh_graph(). Ah well.↩︎

  2. You can read about how to do this in Hadley Wickham’s ‘Mastering Shiny’ book.↩︎

  3. In other words, they’re listed as Imports rather than Suggests in the DESCRIPTION file.↩︎

  4. Using {bslib} is a bit lazy on my part because it makes it really easy to customise the style of a Shiny app, while forcing the user to have to install yet another package. This is not the tinyverse way, so I may refactor one day.↩︎

  5. The ‘thought-of-a-thing-and-then-did-it-sort-of’ approach is very befitting of this blog and very apt given this is post number 100. 🎈↩︎