I am trying to
base64encodematplotlibgenerated plots and write them to a html page on GAE.Later, digitize the plots
Finally, converting the html page to pdf using
xhtml2pdflibrary.
The code worked well if plots are created by jqplot. However once switched to matplotlib, I am having an error called Incorrect padding, which I do not know how to solve. Thanks for any suggestions.
Step 1
Python CODE:
import matplotlib
import matplotlib.pyplot as plt
import StringIO
import urllib, base64
plt.figure(1)
plt.hist([2,3,4,5,6,7], bins=3)
fig = plt.gcf()
imgdata = StringIO.StringIO()
fig.savefig(imgdata, format='png')
imgdata.seek(0) # rewind the data
uri_1 = 'data:image/png;base64,'
uri_2 = urllib.quote(base64.b64encode(imgdata.buf))
uri_2 += "=" * ((4 - len(uri_2 ) % 4) % 4)
uri_3 = uri_1 + uri_2
uri_4 = '<img id="chart1" src = "%s"/>' % (uri_3)
Step 2
Javascript
var n_plot = $('img[id^="chart"]').size();
i=1;
var imgData = [];
while(i <= n_plot){
//sometimes the plots are generated under jqplot
try{
imgData.push($('#chart'+i).jqplotToImageStr({}));
i=i+1
}
// This case is generated by matplotlib
catch(e){
imgData.push($('#chart'+i).attr('src'));
i=i+1
}
}
imgData_json = JSON.stringify(imgData)
Step 3
Python
pdf = pisa.CreatePDF(imgData_json, file(filename, "wb"))
1 Answer 1
That's the problem:
uri_2 += "=" * ((4 - len(uri_2 ) % 4) % 4)
Why do you think the url needs extra padding? The output of b64encode will already be padded if neccessary, adding extra padding will only confuse the decoder. Some may ignore the extra padding, most however will just produce an error.
Oh, and also for data urls it's unnecessary to quote the string - base64 doesn't contain characters that really need to be escaped. That's only needed if you need to use base64 in a regular url, as + and = can cause problems, but that's not the case for data urls.
1 Comment
urllib.quote caused the issue.