I'm trying to run the following R code through my Django application with the end result being a printed R graph in a Python Django webpage. Here is the code for R.
t=read.table(file=file("request.FILES['fileUpload']"))
colnames(t) <- c('x', 'y')
t = data.frame(t)
fit1 = lm(y ~ x, data = t)
par(mfrow=c(1,1))
plot(x=t$x, y=t$y, xlab="x", ylab="y", main="Simple Linear Regression", xlim=c(0,100), ylim=c(0,6), par=20)
abline(fit1, col="red")
Here is something like what I am trying to achieve in the Django function.
from django.shortcuts import render, HttpResponse
import pandas as pd
def upload_files(request):
if request.method == 'POST':
upload = pd.read_table(request.FILES['fileUpload'])
<< Run R Code Here and return the graph >>
response = RGraph
return response
OR
return render(request, 'Regression/index.html', {'graph':response})
return render(request, 'Regression/index.html')
HTML code is as follows.
<html>
<title>Import File</title>
<body>
<h1>Import File</h1>
<hr>
{% if graph %}
<img alt="my base64 graph" src="data:image/png;base64,{{graph}}" />
{% endif %}
<form enctype="multipart/form-data" method="post">
{% csrf_token %}
<input type="file" name="fileUpload" />
<input type="submit" value="Submit" />
</form>
</body>
</html>
As always, thanks for the help.
Using R and Python together at the same time is incredibly easy if you already have your R scripts prepared. Calling them from Python boils down to a single line of code.
It means to treat this string as a literal. Often times you see characters like '\' that need to be escaped, the use of 'r' prevents that from needing to be explicitly written. Follow this answer to receive notifications.
Apparently rpy2 does not provide a direct function which can return a file object to python. So what i recommend is:
On your settings.py define a variable where your R scripts/images should be saved
STATIC_R = 'r_plots'
Model
from django.conf import settings
class RScript(models.Model):
script = FileField(upload_to=settings.STATIC_R)
@property
def script_path(self):
return os.path.basename(self.script.name)
Remember (from docs): FielField.upload_to: A local filesystem path that will be appended to your MEDIA_ROOT setting to determine the value of the url attribute.
Form
class RScriptForm(forms.ModelForm):
class Metal:
model = RScript
fields = ('script',)
Receive your R script and save it
my_plot_script = '''
t=read.table(file=file("{path}"))
colnames(t) <- c('x', 'y')
t = data.frame(t)
fit1 = lm(y ~ x, data = t)
par(mfrow=c(1,1))
png(filename="{path}.png")
plot = plot(x=t$x, y=t$y, xlab="x", ylab="y", main="Simple Linear Regression", xlim=c(0,100), ylim=c(0,6), par=20)
abline(fit1, col="red")
dev.off()
'''
def my_view(request):
if request.method == 'POST':
form = RScriptForm(request.POST)
if form.is_valid():
form.save()
(...)
Now that we have script saved let's try to running it with rpy2
my_plot_script = '''
t=read.table(file=file("{path}"))
colnames(t) <- c('x', 'y')
t = data.frame(t)
fit1 = lm(y ~ x, data = t)
par(mfrow=c(1,1))
png(filename="{path}.png")
plot = plot(x=t$x, y=t$y, xlab="x", ylab="y", main="Simple Linear Regression", xlim=c(0,100), ylim=c(0,6), par=20)
abline(fit1, col="red")
dev.off()
'''
def my_view(request):
context = {}
if request.method == 'POST':
form = RScriptForm(request.POST)
if form.is_valid():
form.save()
import rpy2.robjects as robjects
robjects.r(my_plot_script.format(form.instance.script_path))
context['graph'] = form.instance.script_path + '.png'
return render(request, 'Regression/graph.html', context)
on your template
<html>
<title>Import File</title>
<body>
<h1>Import File</h1>
<hr>
{% if graph %}
<img alt="my base64 graph" src="{{graph}}" />
{% endif %}
<form enctype="multipart/form-data" method="post">
{% csrf_token %}
<input type="file" name="fileUpload" />
<input type="submit" value="Submit" />
</form>
</body>
</html>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With