Creating interactive dashboards in R Shiny using Python scripts as the backend.
Why is it always R v Python? Why can’t we admit that both are unique in their own way and we should know how to leverage both of them at once?
Shiny is an R package that makes it easy to build interactive web apps straight from R. You can host standalone apps on a webpage or embed them in R Markdown documents or build dashboards. You can also extend your Shiny apps with CSS themes, Html widgets, and JavaScript actions.
When I started talking about R and R Shiny, People tend to ask me this question:
Why did you choose Shiny over Dash (By Plotly — Python)? Do they have the same level of complexity ? Which has a bigger community and why would someone prefer one over the other?
Ok, let’s break down the question into three parts.
- Why Shiny over Dash?
- Do they have the same level of Complexity?
- Who has the biggest community?
Here’s the answer:
Currently Shiny is far more mature than Dash. Dash doesn’t have a proper layout tool yet, and also has not built in theme, so if you are not familiar with Html and CSS, your application will not look good (You must have some level of web development knowledge). Also, developing new components will need ReactJS knowledge, which has a steep learning curve.
I would say that right now Shiny might be a little better, especially if your needs are more complex dashboards, but I feel as the Python community is so much larger, Dash is exponentially growing up and it could surpass shiny in general as Python can be used for multiple stuff and who knows what else Dash can evolve to be.
If you’re after a more detailed comparison, click here.
AND… Who said you have to choose between one over another?
Because and this is my answer!: We are data scientists, We know how to code in R and Python both! Why can’t we use R+Python for our development right? It’s not rocket science it’s Data Science and that’s what we good at. Let’s see how to get the maximum out of R and Python for a Shiny Dashboard!
PART 01-CREATING A SHINY APP
The basic parts of a Shiny app
Shiny applications have two components, a user interface object and a server function, that are passed as arguments to the shinyApp
function that creates a Shiny app object from this UI/server pair. The source code for both of these components is listed below.
You can either create one R file named app.R and create two seperate components called (ui and server inside that file) or create two R files named ui.R and server.R (figure 1.0)
In subsequent sections of the article, we’ll break down Shiny code in detail and explain the use of “reactive” expressions for generating output. For now, though, just try playing with the sample application and reviewing the source code to get an initial feel for things. Be sure to read the comments carefully.
The user interface is defined as follows: [Note that I’m going to create one .R file called app.R and will put these two code blocks inside of it]
ui
The server-side of the application is shown below. At one level, it’s very simple — a random distribution is plotted as a histogram with the requested number of bins. However, you’ll also notice that the code that generates the plot is wrapped in a call to renderPlot
. The comment above the function explains a bit about this, but if you find it confusing, don't worry, we'll cover this concept in much more detail soon.
server
# Define server logic required to draw a histogram ----
server <- function(input, output) { # Histogram of the Old Faithful Geyser Data ----
# with requested number of bins
# This expression that generates a histogram is wrapped in a call
# to renderPlot to indicate that:
#
# 1. It is "reactive" and therefore should be automatically
# re-executed when inputs (input$bins) change
# 2. Its output type is a plot
output$distPlot <- renderPlot({ x <- faithful$waiting
bins <- seq(min(x), max(x), length.out = input$bins + 1) hist(x, breaks = bins, col = "#75AADB", border = "white",
xlab = "Waiting time to next eruption (in mins)",
main = "Histogram of waiting times") })}
Finally, we use the shinyApp
function to create a Shiny app object from the UI/server pair that we defined above
We save all of this code, the ui
object, the server
function, and the call to the shinyApp
function, in an R script called app.R
. This is the same basic structure for all Shiny applications.
Your final code should look like this;
Then try to hit run and see what brings out to the browser page:
Try to change the Number of Bins Slider and experience how fast the Histogram making changes to the Number of Bins.
You’re doing good! Let’s have some snacks before moving on to the next phase.
PART II- HOW TO USE PYTHON SCRIPTS INSIDE R SHINY
Now comes the title of my article and the most important part. For an instance, Let’s say that “ I want to get the selected number of bins from the slider and pass that number into a python method and do some calculation/manipulation (return: “You have selected 30bins and I came from a Python Function”) inside of it then return some value back to my R Shiny dashboard and view that results in a text field.”
Whoa! I demand you to go back and read the bold sentence again to make sure that you get the idea and to make things easier I tried to draw my idea on this snip and please don’t mind my handwriting :)
Ok now follow me!
Step 01
Create a textOutput in ui.R to display the final output. To do that, type the following after plotoutput()
textOutput("textOutput")
Step 02
Create a handler on server.R by creating a renderText component for the above created textOutput.
Step 03
Create a new Python script called python_ref.py and insert the following code.
def testMethod(bins): //get number of bins passed by R Shiny server
string = "I came from a Python Function"
noOfBins = str(bins) //convert int to string to concat
return "You have selected " +noOfBins+ " bins and " +string
Your .py file should like the following:
Step 04
Import reticulate library (If you don’t have python reticulate installed in your computer, please refer to this article and this for other information)
library(reticulate)
Step 05
Sourcing Scripts
The source_python()
function will source a Python script and make the objects it creates available within an R environment (by default the calling environment). For example, consider our Python script:
def testMethod(bins): //get number of bins passed by R Shiny server
string = "I came from a Python Function"
noOfBins = str(bins) //convert int to string to concat
return "You have selected " +noOfBins+ " bins and " +string
To access its objects and functions in your R environment, type the following before you start server.R section of your app (You can declare this anywhere in your code outside ui.R and server.R, Best practice to use before server.R)
Step 06
OK guys, We’re almost there. Now before finalizing it make sure that you have two files inside your directory called
and you have imported the reticulate package to R Environment and sourced the script inside your R code.
Let’s hit Run see if we succeeded or not! :)
Output:
TIME FOR ANOTHER CELEBRATION!
I have deployed this application on shinyapps.io so you can have the experience for yourself. ( Click on below Link )
I’ve uploaded the files to my GitHub so you can download and try to play with it using different components and python functions. Let me know if you run into any issues I’m more than happy to help you out.
Keen on getting to know me and my work? Click here for more!
Meanwhile, check my other posts as well:
THANK YOU SO MUCH!
Originally published at https://www.jayasekara.blog.