Model card fails to show plots - python

I am trying to add a .png image to my model card. But it keeps giving a blank picture. I followed the instruction given by Google.
Here is what my code looks like,
from io import BytesIO
import base64
from google.colab import files
def plot_to_str():
img = BytesIO()
plt.savefig(img, format='png')
return base64.encodebytes(img.getvalue()).decode('utf-8')
my_plot = files.upload()
my_plot = plot_to_str()
And for the model card:
mct = mctlib.ModelCardToolkit()
model_card = mct.scaffold_assets()
# skipped the beginning of the model_card
model_card.model_parameters.data.append(mctlib.Dataset())
model_card.model_parameters.data[0].graphics.collection = [
mctlib.Graphic(image=my_plot)
]
mct.update_model_card(model_card)
html = mct.export_format()
display.display(display.HTML(html))
As a result I get this, a blan plot:

Related

Python, JSignature, and ReportLab

I'm looking to write a signature to PDF. I'm using JSignature and Reportlab. My code works successfully for writing the data to a file and the database. I just cannot figure out how to write the signature to the canvas. Has anyone passed the signature into the canvas successfully?
Thank you in advance.
Here's a look at my code:
pdf.py
import io
from django.core.files.base import ContentFile
from reportlab.lib.units import inch
from reportlab.pdfgen import canvas
from reportlab.lib.utils import ImageReader
def create_pdf(parent):
# create a file-like buffer to receive PDF data
buffer = io.BytesIO()
# create the pdf object, using the buffer as its "file"
p = canvas.Canvas(buffer)
# create text
textobject = p.beginText()
# start text at top left of page
textobject.setTextOrigin(inch, 11*inch)
# set font and size
textobject.setFont("Helvetica-Bold", 18)
textobject.textLine("My Document")
textobject.textLine("")
# write page 1
textobject.setFont("Helvetica", 12)
p_name = f'Name: {participant.first_name} {participant.middle_initial} {participant.last_name}'
textobject.textLine(p_name)
sig = f'Signature:'
textobject.textLine(sig)
----insert signature here----
# write created text to canvas
p.drawText(textobject)
# close the pdf canvas
p.showPage()
p.save()
buffer.seek(0)
# get content of buffer
pdf_data = buffer.getvalue()
# save to django File object
file_data = ContentFile(pdf_data)
# name the file
file_data.name = f'{participant.last_name}.pdf'
#
participant.pdf = file_data
participant.save()
Model:
class Participant(models.Model):
first_name = models.CharField(max_length=50)
middle_initial = models.CharField(max_length=50, blank=True)
last_name = models.CharField(max_length=50, blank=True)
signature = JSignatureField()
pdf = models.FileField(blank=True, null=True)
For those interested in how I was able to get this functioning. The primary issue was The image would be completely black when pulling it into the PDF. Here’s what is required:
In your View:
Use the Jsignature draw_signature function and get the image:
rsr_image = draw_signature(signature)
save the signature as a PNG and then store
# save signature as png to prevent darkening, save to model
rsr_file_name = str(new_parent.id)+'_rsr.png'
buffer = BytesIO()
rsr_image.save(buffer, 'PNG')
new_parent.rsr_image.save(rsr_file_name, File(buffer))
Create the following function, in order to…
Open the image, create a new background for the image, and save it.
def get_jpeg_image(new_parent):
# open png image
png_image = Image.open(new_parent.rsr_image)
# create new image with 'RGB' mode which is compatible with jpeg,
# with same size as old and with white(255,255,255) background
bg = Image.new("RGB", png_image.size, (255, 255, 255))
# paste old image pixels in new background
bg.paste(png_image, png_image)
# give image file name
file_name_jpeg = str(new_parent.id)+'.jpg'
bg.save(file_name_jpeg)
return file_name_jpeg
Reference that function inside your create PDF function to convert the PNG to JPG
jpeg_image = get_jpeg_image(participant)
Hope this helps someone.

Image does not exist

I want to print images in word so that I can print them easier, same size, etc.
I use this piece of code:
from docxtpl import DocxTemplate
from docxtpl import InlineImage
from docx.shared import Mm
import os
folder = "./mercedes/"
for img_name in os.listdir(folder):
doc = DocxTemplate("C:\\Users\\jpp08\\Documents\\MIDDELKOOP\\testimg.docx")
img1 = InlineImage(doc, image_descriptor=f'{img_name}', width=Mm(20), height=Mm(10))
context = {'img1': img1}
doc.render(context)
doc.save(f"{folder}/{img_name}" +".docx")
But I got the error that "name of picture".jpg does not exist. But it's the right name and right location.

how to add multiple pdfs to be converted into excel?

I have program which converts pdf to excel, Now i want add multiple inputs i.e. multiple pdfs to be converted one by one.
my code is below:
from PIL import Image
import io
import pytesseract
from wand.image import Image as wi
import os
import cv2
import pandas as pd
import re
import numpy as np
import os
pdf = wi(filename= "pdfs/jaalna.pdf", resolution =300)
pdfImage = pdf.convert("jpg")
imageBlobs = []
for img in pdfImage.sequence:
imgPage = wi(image = img)
#img.filter(ImageFilter.EDGE_ENHANCE_MORE )
imageBlobs.append(imgPage.make_blob('jpg'))
recognized_text = []
for imgBlob in imageBlobs:
im = Image.open(io.BytesIO(imgBlob))
text = pytesseract.image_to_string(im, lang = 'eng1+mar1')
recognized_text.append(text)
newfile = open('aama.txt','w')
newfile.write(",".join(recognized_text))
#add a folder as input.
you can use loop
for name in ["pdfs/jaalna.pdf", "other/file.pdf"]:
pdf = wi(filename=name, resolution=300)
# rest of code
or you can use sys.argv to get names as
script.py pdfs/jaalna.pdf other/file.pdf other/third.pdf
and code
import sys
for name in sys.argv[1:]:
pdf = wi(filename=name, resolution=300)
# rest of code
Try the code below. This will loop through every PDF file in the folder directory you define. Be sure to update your file_path to be where your PDFs are saved, making sure you use double backslashs in place of single backslashes.
from PIL import Image
import io
import pytesseract
from wand.image import Image as wi
import cv2
import pandas as pd
import re
import numpy as np
import os
file_path = "C:\\Users\\..."
for file in os.listdir(file_path):
if file.endswith(".pdf"):
pdf = wi(file, resolution =300)
pdfImage = pdf.convert("jpg")
imageBlobs = []
for img in pdfImage.sequence:
imgPage = wi(image = img)
#img.filter(ImageFilter.EDGE_ENHANCE_MORE )
imageBlobs.append(imgPage.make_blob('jpg'))
recognized_text = []
for imgBlob in imageBlobs:
im = Image.open(io.BytesIO(imgBlob))
text = pytesseract.image_to_string(im, lang = 'eng1+mar1')
recognized_text.append(text)
newfile = open(file+'.txt','w')
newfile.write(",".join(recognized_text))
#add a folder as input.

Pillow data handling

I want to use pillow for saving Image and loading it.
I know I can do Image.save(imagename.xxx).
But I want to save as the contents of images.
and I want to reuse it .
from PIL import Image
import numpy as np
filename = 'any_image.png'
import pickle
im = Image.open(filename)
data = list(im.getdata())
f = open("test_file.dat","wb")
dumps = pickle.dump(data,f)
f = open("test_file.dat","rb")
tumps = pickle.load(f)
print(np.asarray(tumps))
#here
re_im = Image.Image.putdata(tumps)
re_im.show()
I want to show re_im Image Object, it is the same contents I saved before.
I could save & load of the same contents by pickle.
But I don't know where I send the contents.
I want to show the same as original image by re_im.show()
please help me.
I could make it.
first, to omit 'data = list(im.getdata())'
second, to insert 'np.array(im)'
from PIL import Image
import numpy as np
filename = 'any_data.png'
import pickle
im = Image.open(filename)
data = np.array(im)
f = open("test_file.dat","wb")
print(type(data))
dumps = pickle.dump(data,f)
f = open("test_file.dat","rb")
tumps = pickle.load(f)
array = Image.fromarray(tumps)
array.show()

Matplotlib graphic image to base64

Problem : Need to transform a graphic image of matplotlib to a base64 image
Current Solution : Save the matplot image in a cache folder and read it with read() method and then convert to base64
New Problem : Annoyance : Need a workaround so I dont need to save the graphic as image in any folder. I want to just use the image in the memory. Doing unnecessary I/O is a bad practice.
def save_single_graphic_data(data, y_label="Loss", x_label="Epochs", save_as="data.png"):
total_epochs = len(data)
plt.figure()
plt.clf()
plt.plot(total_epochs, data)
ax = plt.gca()
ax.ticklabel_format(useOffset=False)
plt.ylabel(y_label)
plt.xlabel(x_label)
if save_as is not None:
plt.savefig(save_as)
plt.savefig("cache/cached1.png")
cached_img = open("cache/cached1.png")
cached_img_b64 = base64.b64encode(cached_img.read())
os.remove("cache/cached1.png")
return cached_img_b64
import cStringIO
my_stringIObytes = cStringIO.StringIO()
plt.savefig(my_stringIObytes, format='jpg')
my_stringIObytes.seek(0)
my_base64_jpgData = base64.b64encode(my_stringIObytes.read())
[edit] in python3 it should be
import io
my_stringIObytes = io.BytesIO()
plt.savefig(my_stringIObytes, format='jpg')
my_stringIObytes.seek(0)
my_base64_jpgData = base64.b64encode(my_stringIObytes.read()).decode()
I think at least ... based on the documentation http://matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.savefig
For python 3
import base64
import io
pic_IObytes = io.BytesIO()
plt.savefig(pic_IObytes, format='png')
pic_IObytes.seek(0)
pic_hash = base64.b64encode(pic_IObytes.read())
The reason is both cStringIO and cStringIO.StringIO() are deprecated
I could not get answers above work, but this did:
import io
import base64
s = io.BytesIO()
plt.plot(list(range(100)))
plt.savefig(s, format='png', bbox_inches="tight")
plt.close()
s = base64.b64encode(s.getvalue()).decode("utf-8").replace("\n", "")
return '<img align="left" src="data:image/png;base64,%s">' % s

Categories