How to make simple graphs in python 2.7 - python

I would like to make simple graphs for my web page in python/django, but I do not know, which library (and how) to use.
I DO NOT WANT CHARTS, I SEEK A WAY TO CREATE IMAGE FROM PRIMITIVES LIKE RECTANGLES.
Each such graph is probabely generated and used only one time, as next time the values would differ.
I can simply compute the positions of all rectangles, lines or texts in it, so I would like something lightweight to just create pictre from that, which I would return as img/png (or so) mime style
like <img src="http://my.web.www/my/page/graph" > where the parameters to show would be decidied by session and database.
I can compute all the sizes beforehand, so I would like something simple like
img=Image(PNG,598,89) # style, x, y
img.add_text('1.3.', 10,10)
img.add_rectagle(20,10, 70,20, CYAN, BLACK)
....
return img.render()
Can you direct me, how to do it?
Thanks beforehand
navit nailed it :)
# from django.utils.httpwrappers import HttpResponse
from PIL import Image, ImageDraw
import os,sys
im = Image.new('RGB',(598,89),'white')
draw = ImageDraw.Draw(im)
draw.rectangle((0,0,im.size[0]-1,im.size[1]-1), outline='blue')
draw.rectangle((25,10,590,20), fill='white', outline='black')
draw.rectangle((25,10,70,20), fill='rgb(255,0,0)', outline='black')
draw.rectangle((70,10,90,20), fill='green', outline='black')
draw.text((1,10),'1.3.',fill='black')
del draw
# write to stdout
im.save(sys.stdout, "PNG")
# draw.flush()
# response = HttpResponse(mimetype="image/png")
# image.save(response, "PNG")
# return response

You should check Pillow out. Here is a sample how it works:
from PIL import Image, ImageDraw
im = Image.open("lena.pgm")
draw = ImageDraw.Draw(im)
draw.line((0, 0) + im.size, fill=128)
draw.line((0, im.size[1], im.size[0], 0), fill=128)
del draw
# write to stdout
im.save(sys.stdout, "PNG")
Serving a file from Pillow to your client should be straightforward. Let me know if you have a question.
edit: found these examples to get you started.

http://matplotlib.org/ permits to generate plenty of great graphs. You should be able to save it as an image and integrate it to your webpage

What about plotly? Never used in a project, but by reading the examples it seems very powerful and easy to use. It has a static image export (as most graphic libraries probably have).

Related

PIL Gif generation not working as expected

What I'm trying to do: Since I'm still quite new to image generation using the PIL library, I decided to experiment with putting images on top of gifs. There were not a lot of proper tutorials or references I could use.
What's going wrong: More often than not, the gif would not be generated. This would give the error IndexError: bytearray index out of range which I'm not sure how to fix. However, sometimes the gif would be generated, but there would be some errors. I have included some of these gifs below.
The code:
#client.command()
async def salt(ctx, user:discord.Member=None):
if user == None:
user = ctx.author
animated_gif = Image.open("salty.gif")
response = requests.get(user.avatar_url)
background = Image.open(BytesIO(response.content))
all_frames = []
# background = background.resize((500, 500))
for gif_frame in ImageSequence.Iterator(animated_gif):
# duplicate background image
new_frame = background.copy()
# need to convert from `P` to `RGBA` to use it in `paste()` as mask for transparency
gif_frame = gif_frame.convert('RGBA')
# paste on background using mask to get transparency
new_frame.paste(gif_frame, mask=gif_frame)
all_frames.append(new_frame)
# save all frames as animated gif
all_frames[0].save("image.gif", save_all=True, append_images=all_frames[1:], duration=50, loop=0)
This is the gif I am using:
Unfortunately animated GIF support in PIL is faulty, and hard to work with at all. The images you are showing suffer from the layers sharing the palette information with the background layer, so they have some of their colors distorted.
I don't know if there is a way to control the palette information for each frame using PIL.
If you want to generate GIFs progamaticaly using Python, I'd, for now, recommend that you use the GIMP Image editor - there you can build your image, either interactively using the program, or programaticaly, using the Python console, and just call the "save as gif" function (pdb.file_gif_save2).
(I will take a look at PILs exact capabilities, and check if I can extend the answer on proper handling of transparency - otherwise, GIMP is the way to go)

Python creating a function that pulls a picture from a url then resizing to thumbnail

So I have been having problems trying to write the function to change the size of an image if to big and saving it as a thumbnail. I have how to retrieve the image just lost after that. I know about pillow but cant use for the class any help would be appreciated.
Update: So far I have gotten the code to resize the image and make it a thumbnail. The next part that I am on is having it save if resized to thumbnail2, but if it stays the same save as thumbnail1. Here is my code so far without the next step.
import urllib
url ="https://upload.wikimedia.org/wikipedia/commons/4/47/PNG_transparency_demonstra ion_1.png"
src = "C:\Users\laramie\Pictures\PNG_transparency_demonstration_1.png"
connect = urllib.urlretrieve(url, src)
def scalePicture(src):
newWidth = getWidth(src)/2
newHeight = getHeight(src)/2
canvas = makeEmptyPicture(newWidth, newHeight)
for x in range(newWidth):
for y in range(newHeight):
setColor(getPixel(canvas, x,y), getColor(getPixel(src, x*2, y*2)))
return canvas
def thumbNail():
srcPic = makePicture(src)
destWidth = getWidth(srcPic) / 2
destHeight = getHeight(srcPic) / 2
destPic = makeEmptyPicture(destWidth, destHeight)
destPic = scalePicture(srcPic)
show(srcPic)
show(destPic)
thumbNail()
There are a bunch of strange things going on in your code:
destPic = makeEmptyPicture(destWidth, destHeight)
destPic = scalePicture(srcPic)
the first line here is not required, because the destPic is overwritten immediately.
for x in range(newWidth):
for y in range(newHeight):
setColor(getPixel(canvas, x,y), getColor(getPixel(src, x*2, y*2)))
Ths is a very inefficient way to scale an image, that gives inferior results, unless the scale factor is an integer, and even then there are faster and better approaches.
I would recommend you to import PIL (Python Image Library) and use it to work with images. Things like loadng, saving, scaling or flipping images are easily done. However, you may need to install this library if it did not come with your python installation.

How to properly scale/rotate images in pyqtgraph?

I have implemented pyqtgraph inside QGraphicsView in PyQt5. When I display the image the following way, it is stretched out and expands in the same aspect ratio as the screen. How do I fix this?
image = pg.ImageItem(asarray(Image.open('pic.png')) )
self.graphicsView.addItem(image)
image.rotate(270)
EDIT: found out how to rotate image, so I updated question with the solution. Now I am just trying to scale it properly.
You probably want something like:
import pyqtgraph as pg
from PIL import Image
from numpy import asarray
app = pg.mkQApp()
# Set up a window with ViewBox inside
gv = pg.GraphicsView()
vb = pg.ViewBox()
gv.setCentralItem(vb)
gv.show()
# configure view for images
vb.setAspectLocked()
vb.invertY()
# display image
img_data = asarray(Image.open('/home/luke/tmp/graph.png'))
image = pg.ImageItem(img_data, axisOrder='row-major')
vb.addItem(image)
The important pieces here that set the image scaling/orientation are:
using ImageItem(axisOrder='row-major') because image files are stored in row-major order
vb.invertY() because image files have the +y axis pointing downward
and vb.setAspectLocked() to keep the pixels square
I used np.rot90() instead, it's much faster and cythonable
image = pg.ImageItem(np.rot90(np.asarray(Image.open('pic.png'))))

Python svgwrite module background color

I am using the svgwrite module in my Python code and I would like to set a background color. So far I have not been able to find anything. Is there a way to do it?
I was hoping for something during the initialization:
import svgwrite
canvas = svgwrite.drawing.Drawing(fill="#225566") # or background="#225566", or sth similar
canvas.save('image.png')
Or I could probably draw rectangle all over the place, but that's just weird.
It seems that svg itself does not define how to set the background colour. For svgwrite I use this:
svg_size_width = 900
svg_size_height = 4500
dwg = svgwrite.Drawing(name, (svg_size_width, svg_size_height), debug=True)
dwg.add(dwg.rect(insert=(0, 0), size=('100%', '100%'), rx=None, ry=None, fill='rgb(50,50,50)'))
dwg.save()

Functions in Python (pygame)

Apologies in advance if this is a simple fix (I am relatively new to programming). I am creating a python game (with pygame) that will include a lot of images. I am currently using the following code to import and scale the pictures according to the screen resolution:
pygame.init()
WINDOW= pygame.display.Info() # size of window's width in pixels
WINDOWW = WINDOW.current_w
WINDOWH = WINDOW.current_h
size = 1920/WINDOWW
CreditsL = pygame.image.load ('TEXT\Credits.png')
Creditsrect= CreditsL.get_rect()
Credits = pygame.transform.scale(CreditsL, (int(Creditsrect.w/size), int(Creditsrect.h/size)))
Since I have to import tons of images I would like to know how I can make a function that will import and scale the pictures, instead of me having to copy and paste.
Thanks in advance
def resize(imgpath):
img = pygame.image.load(imgpath)
rect = img.get_rect()
return pygame.transform.scale(img, (int(rect.w/size), int(rect.h/size)))
Credits = resize('TEXT\Credits.png')
If you want to avoid having to copy-paste this last line for each and every image, use a list of [(name, path),] tuples and build a dict from it:
SOURCES = [
("credit", 'TEXT\Credits.png'),
("something", 'TEXT\whatever.png'),
# etc
]
IMAGES = dict((name, resize(path)) for name, path in SOURCES)
Then to use the resized "credit" image :
do_something_with(IMAGES["credit"])
It is pretty easy to wrap your current code lines into a function and call it:
def importer(path):
CreditsL = pygame.image.load(path)
Creditsrect = CreditsL.get_rect()
return pygame.transform.scale(CreditsL,
(int(Creditsrect.w/size),
int(Creditsrect.h/size)))
Credits = importer('TEXT\Credits.png')
Scaling the image through pygame, from my understandings, is not the way to go. Use a simple photo editor (Paint if you gotta!) to scale your image accordingly. It is more work for the computer to do. The more work your computer does, the less efficient the game! Memory might not be an issue now, but it would probably be wise to make good practice, as well as make your code easier to look at.

Categories

Resources