Search code examples
pythonrr-markdownreticulate

How to display a geometric object from Python code in a Rmarkdown document?


I would like to have a point displayed (like in this tutorial) in my rmarkdown document after knitting.

Reproducible example:

---
title: "Reprex"
output: html_document
---

```{python}
# Import necessary geometric objects from shapely module
from shapely.geometry import Point, LineString, Polygon

# Create Point geometric object(s) with coordinates
point1 = Point(2.2, 4.2)

point1
```

With this code, I only get the following output:

## <shapely.geometry.point.Point object at 0x0000000026EEA0B8>

How can I have the image of the point displayed instead?

Also, I am interested to display it in the viewer/plot pane.


Solution

  • First, not sure if this is crucial, but, following the documentation, we need to add this chunk first:

    ```{r setup, include=FALSE}
    library(knitr)
    library(reticulate)
    knitr::knit_engines$set(python = reticulate::eng_python)
    ```
    

    What you want to get is Jupyter-specific functionality. I was able to reproduce it only by converting the point(s) to pure SVG via _repr_svg_() function:

    ```{python}
    from shapely.geometry import Point, LineString, Polygon, MultiPoint
    
    point1 = Point(2.2, 4.2)
    point2 = Point(7.2, -25.1)
    point3 = Point(9.26, -2.456)
    point3D = Point(9.26, -2.456, 0.57)
    
    multipoints = MultiPoint([point1, point2, point3, point3D])
    svg = multipoints._repr_svg_()
    
    # or, in your case
    
    svg = point1._repr_svg_()
    ```
    

    Then displaying it with R chunk:

    ```{r}
    htmltools::HTML(py$svg)
    ```
    

    I tried doing it on Python-side only (calling r.HTML()), which will only result in textual output.

    Note that this will result in the following warning:

    sys:1: ShapelyDeprecationWarning: __len__ for multi-part geometries is deprecated and will be removed in Shapely 2.0. Check the length of the `geoms` property instead to get the  number of parts of a multi-part geometry.
    

    But you can ignore it, it still draws the points:

    enter image description here enter image description here

    Full code:

    ---
    title: "Reprex"
    output: html_document
    ---
    
    ```{r setup, include=FALSE}
    library(knitr)
    library(reticulate)
    knitr::knit_engines$set(python = reticulate::eng_python)
    ```
    
    ```{python}
    from shapely.geometry import Point, LineString, Polygon, MultiPoint
    
    point1 = Point(2.2, 4.2)
    point2 = Point(7.2, -25.1)
    point3 = Point(9.26, -2.456)
    point3D = Point(9.26, -2.456, 0.57)
    
    multipoints = MultiPoint([point1, point2, point3, point3D])
    svg = multipoints._repr_svg_()
    
    # or, in your case
    
    svg = point1._repr_svg_()
    ```
    
    ```{r}
    htmltools::HTML(py$svg)
    ```