Creating the Python Script
Now that we’re set up to create a Ligare application, let’s see how to integrate an R script into it.
For the purpose of this guide, we’re going to create a single Python Script and a single R script. The R script will read in method arguments and data, then output a plot.
Our final Python script will look like this.
#!/usr/bin/env python3
# Can be executed like `python draw_plot.py > ligare.png`
if __name__ != "__main__":
raise Exception("Cannot be imported.")
import sys
from os import path
from pathlib import Path
from Ligare.programming.R.process import RProcessStepBuilder
exec_dir = path.abspath(".")
script_path = Path(exec_dir, "draw_plot.R")
# get the line segments that R will turn into a dataframe
with open(Path(exec_dir, "letter_segments.csv"), "rb") as f:
data = f.read()
executor = (
RProcessStepBuilder()
.with_Rscript_binary_path("/usr/bin/Rscript")
# make `draw_plot.R` output a PNG. TIFF is also supported.
.with_args(["--output-type=png"])
.with_R_script_path(script_path)
# These are the method parameters for the
# R method `draw_lines_from_dataframe`.
.with_method_parameters({
"spacing": 1.2,
"line_width": 6,
"color": "green",
"background_color": "black",
})
.with_data(data)
)
(proc, img_data) = executor.execute()
_ = sys.stdout.buffer.write(img_data)
_ = sys.stdout.buffer.flush()
Using RProcessStepBuilder
The main point of integration is RProcessStepBuilder
.
Note
A Step Builder is a design pattern to help configure an object.
In this case, RProcessStepBuilder
configures the Rscript
command
needed to execute an R script.
Let’s start with configuring the Rscript
executable.
r_process_builder = RProcessStepBuilder()
r_process_script_builder = r_process_builder \
.with_Rscript_binary_path("/usr/bin/Rscript")
By doing this, we’re telling the builder where the Rscript
executable is. This
is the command that will execute your R script.
Note
If /usr/bin/Rscript
does not exist on your system,
replace the value with the path to your Rscript
command.
Next, we will configure options for the R script itself.
r_script_method_builder = r_process_script_builder \
.with_args(["--output-type=png"]) \
.with_R_script_path("draw_plot.R")
This creates a command that is equiavlent to /usr/bin/Rscript draw_plot.R --output-type=png
With the R script path and commandline options configured, we now need to configure the method that the R script executes to draw a plot.
r_executor_builder = r_script_method_builder \
.with_method_parameters({
"spacing": 1.2,
"line_width": 6,
"color": "green",
"background_color": "black",
}) \
.with_data(data) # we will read data from a CSV
With the R script that we will write, this causes the R script to execute the equivalent of this.
draw_lines_from_dataframe(
data,
spacing=1.2,
line_width=6,
color="green",
background_color="black"
)
Reading and Writing Data
The R script we will write expects to receive a CSV that will be parsed into a dataframe.
For this example, you can use the Review example sources [R-integration/letter_segments.csv] CSV.
We’ll need to read this CSV file in the Python script. This is the value of data
that
we used for with_data(data)
.
with open(Path(exec_dir, "letter_segments.csv"), "rb") as f:
data = f.read()
And lastly, our R script writes PNG data to its STDOUT, which means Python needs to read that data and pass it along to its own STDOUT. We also need to wrap up our Python script by executing the R script.
(proc, img_data) = r_executor_builder.execute()
_ = sys.stdout.buffer.write(img_data)
_ = sys.stdout.buffer.flush()