Search code examples
rr-markdownflexdashboardreticulate

Showing Seaborn Plots from R Markdown (flexdashboard)


I was wondering if anyone had any insights around displaying a Seaborn Python plot in R Markdown with {reticulate}.

For reproducibility, here's an example from this article: https://towardsdatascience.com/python-seaborn-plots-in-r-using-reticulate-fb59cebf61a7

Setup:

library(reticulate)
#importing required Python libraries/modules
sns <- import('seaborn')
plt <- import('matplotlib.pyplot')
pd <- import('pandas')

Chart:

#using R's inbuilt AirPassengers dataset
df <- datasets::AirPassengers
#converting Time-Series object into an R Dataframe 
#Thx: https://stackoverflow.com/questions/5331901/transforming-a-time-series-into-a-data-frame-and-back
df1 <- data.frame(tapply(df, list(year = floor(time(df)), month = month.abb[cycle(df)]), c))
df1 <- df1[month.abb]
#building a heatmap using seaborn 
#please note the function r_to_py() that converts R object into a python 
sns$heatmap(r_to_py(df1), fmt="g", cmap ='viridis')
#display the plot
plt$show()

This shows up as expected within the RStudio Plots pane: enter image description here

But producing the same plot when knitting an .Rmd file (flexdashboard), it pops up a viewer, and after I close it the report gets rendered this way: enter image description here

Flexdashboard code (two backticks on code chunks instead of 3 for formatting):

---
title: "Untitled"
output: 
  flexdashboard::flex_dashboard:
    orientation: columns
    vertical_layout: fill
---

``{r setup, include=FALSE}
library(reticulate)
#importing required Python libraries/modules
sns <- import('seaborn')
plt <- import('matplotlib.pyplot')
pd <- import('pandas')
``

Column {data-width=650}
-----------------------------------------------------------------------

### Chart A

``{r}
#using R's inbuilt AirPassengers dataset
df <- datasets::AirPassengers
#converting Time-Series object into an R Dataframe 
#Thx: https://stackoverflow.com/questions/5331901/transforming-a-time-series-into-a-data-frame-and-back
df1 <- data.frame(tapply(df, list(year = floor(time(df)), month = month.abb[cycle(df)]), c))
df1 <- df1[month.abb]
#building a heatmap using seaborn 
#please note the function r_to_py() that converts R object into a python 
sns$heatmap(r_to_py(df1), fmt="g", cmap ='viridis')
#display the plot
plt$show()
``

Any thoughts on how to show seaborn plot in flexdashboard here?


Solution

  • Avoid showing the plot, save the seaborn plot to a file and then use Markdown to view it. A bit ugly but it works.

    ```{r}
    #using R's inbuilt AirPassengers dataset
    df <- datasets::AirPassengers
    #converting Time-Series object into an R Dataframe 
    #Thx: https://stackoverflow.com/questions/5331901/transforming-a-time-series-into-a-data-frame-and-back
    df1 <- data.frame(tapply(df, list(year = floor(time(df)), month = month.abb[cycle(df)]), c))
    df1 <- df1[month.abb]
    #building a heatmap using seaborn 
    #please note the function r_to_py() that converts R object into a python 
    # assign the result of the heatmap to a variable so it doesn't get shown
    ss <- sns$heatmap(r_to_py(df1), fmt="g", cmap ='viridis')
    #save the plot
    plt$savefig('passenger_heatmap.png')
    # Avoid the pop up by not showing the plot
    #plt$show()
    ```
    
    ![heatmap](passenger_heatmap.png)