How to draw polygons with Python?

前端 未结 6 998
南笙
南笙 2021-02-05 08:38

I have input values of x, y coordinates in the following format:

[[1,1], [2,1], [2,2], [1,2], [0.5,1.5]]

I want to draw polygons, but I don\'t

相关标签:
6条回答
  • 2021-02-05 08:55

    Also, if you're drawing on window, use this:

    dots = [[1,1], [2,1], [2,2], [1,2], [0.5,1.5]]
    from tkinter import Canvas
    c = Canvas(width=750, height=750)
    c.pack()
    out = []
    for x,y in dots:
        out += [x*250, y*250]
    c.create_polygon(*out, fill='#aaffff')#fill with any color html or name you want, like fill='blue'
    c.update()
    

    or also you may use this:

    dots = [[1,1], [2,1], [2,2], [1,2], [0.5,1.5]]
    out = []
    for x,y in dots:
        out.append([x*250, y*250])
    import pygame, sys
    from pygame.locals import *
    pygame.init()
    DISPLAYSURF = pygame.display.set_mode((750, 750), 0, 32)
    pygame.display.set_caption('WindowName')
    DISPLAYSURF.fill((255,255,255))#< ; \/ - colours
    pygame.draw.polygon(DISPLAYSURF, (0, 255,0), out)
    while True:
        for event in pygame.event.get():
            if event.type == QUIT:
                pygame.quit()
                sys.exit()
        pygame.display.update()
    

    First needs tkinter, second - pygame. First loads faster, second draws faster, if you put DISPLAYSURF.fill and than pygame.draw.polygon with a bit different coordinates into loop, it will work better than the same thing in tkinter. So if your polygon is flying and bouncing around, use second, but if it's just stable thing, use first. Also, in python2 use from Tkinter, not from tkinter. I've checked this code on raspberrypi3, it works.

    ------------EDIT------------

    A little bit more about PIL and PYPLOT methods, see another answers:

    matplotlib uses tkinter, maybe matplotlib is easier-to-use, but it's basically cooler tkinter window.

    PIL in this case uses imagemagick, which is really good image editing tool

    If you also need to apply effects on image, use PIL.

    If you need more difficult math-figures, use matplotlib.pyplot.

    For animation, use pygame.

    For everything you don't know any better way to do something, use tkinter.

    tkinter init is fast. pygame updates are fast. pyplot is just a geometry tool.

    0 讨论(0)
  • 2021-02-05 09:01

    All the other answers seems veryhigh level, I guess that is my impression as a mechanical engineer. Here's a simple version of the code:

    from numpy import *
    from matplotlib.pyplot import *
    x = ([1,2,2,1,0.5,1]) 
    y = ([1,1,2,2,1.5,1])
    plot(x,y)
    show()
    
    0 讨论(0)
  • 2021-02-05 09:06

    If you want to draw polygons on a matrix representing an image, scikit-image has 3 functions for you:

    • skimage.draw.polygon2mask(image_shape, polygon) that directly returns a bool-type numpy.array where True means the point is inside the polygon.
    • skimage.draw.polygon(r, c[, shape]) that returns the row and column indices of the matrix points that are inside the polygon. This function is called internally by polygon2mask().
    • skimage.draw.polygon_perimeter(r, c[, shape[, clip]]) that returns the row and column indices of the points that best represent the perimeter of the polygon. This can include points that polygon() would have let aside.

    Correct me if your benchmark said the contrary, but I think these functions are quite fast.

    Example

    import numpy as np
    from skimage.draw import polygon2mask, polygon, polygon_perimeter
    
    shape = (10, 10)  # image shape
    points = [(5, -1), (-1, 5), (5, 11), (10, 5)]  # polygon points
    
    imgp2 = polygon2mask(shape, points).astype(str)  # astype() converts bools to strings
    imgp2[imgp2 == "True"] = "O"
    imgp2[imgp2 == "False"] = "."
    
    imgp = np.full(shape, ".")  # fill a n*d matrix with '.'
    imgpp = imgp.copy()
    points = np.transpose(points)  # change format to ([5, -1, 5, 10], [-1, 5, 11, 5])
    
    rr, cc = polygon(*points, shape=shape)
    imgp[rr, cc] = "O"
    
    rr, cc = polygon_perimeter(*points, shape=shape, clip=True)
    imgpp[rr, cc] = "O"
    
    print(imgp2, imgp, imgpp, sep="\n\n")
    

    Result:

    [['.' '.' '.' '.' 'O' 'O' '.' '.' '.' '.']
     ['.' '.' '.' 'O' 'O' 'O' 'O' '.' '.' '.']
     ['.' '.' 'O' 'O' 'O' 'O' 'O' 'O' '.' '.']
     ['.' 'O' 'O' 'O' 'O' 'O' 'O' 'O' 'O' '.']
     ['O' 'O' 'O' 'O' 'O' 'O' 'O' 'O' 'O' 'O']
     ['O' 'O' 'O' 'O' 'O' 'O' 'O' 'O' 'O' 'O']
     ['.' 'O' 'O' 'O' 'O' 'O' 'O' 'O' 'O' 'O']
     ['.' '.' 'O' 'O' 'O' 'O' 'O' 'O' 'O' '.']
     ['.' '.' '.' 'O' 'O' 'O' 'O' 'O' '.' '.']
     ['.' '.' '.' '.' 'O' 'O' 'O' '.' '.' '.']]
    
    [['.' '.' '.' '.' 'O' 'O' '.' '.' '.' '.']
     ['.' '.' '.' 'O' 'O' 'O' 'O' '.' '.' '.']
     ['.' '.' 'O' 'O' 'O' 'O' 'O' 'O' '.' '.']
     ['.' 'O' 'O' 'O' 'O' 'O' 'O' 'O' 'O' '.']
     ['O' 'O' 'O' 'O' 'O' 'O' 'O' 'O' 'O' 'O']
     ['O' 'O' 'O' 'O' 'O' 'O' 'O' 'O' 'O' 'O']
     ['.' 'O' 'O' 'O' 'O' 'O' 'O' 'O' 'O' 'O']
     ['.' '.' 'O' 'O' 'O' 'O' 'O' 'O' 'O' '.']
     ['.' '.' '.' 'O' 'O' 'O' 'O' 'O' '.' '.']
     ['.' '.' '.' '.' 'O' 'O' 'O' '.' '.' '.']]
    
    [['.' '.' '.' '.' 'O' 'O' 'O' '.' '.' '.']
     ['.' '.' '.' 'O' '.' '.' '.' 'O' '.' '.']
     ['.' '.' 'O' '.' '.' '.' '.' '.' 'O' '.']
     ['.' 'O' '.' '.' '.' '.' '.' '.' '.' 'O']
     ['O' '.' '.' '.' '.' '.' '.' '.' '.' 'O']
     ['O' '.' '.' '.' '.' '.' '.' '.' '.' 'O']
     ['O' '.' '.' '.' '.' '.' '.' '.' '.' 'O']
     ['.' 'O' 'O' '.' '.' '.' '.' '.' '.' 'O']
     ['.' '.' '.' 'O' '.' '.' '.' 'O' 'O' '.']
     ['.' '.' '.' '.' 'O' 'O' 'O' '.' '.' '.']]
    
    0 讨论(0)
  • 2021-02-05 09:07

    Using matplotlib.pyplot

    import matplotlib.pyplot as plt
    
    coord = [[1,1], [2,1], [2,2], [1,2], [0.5,1.5]]
    coord.append(coord[0]) #repeat the first point to create a 'closed loop'
    
    xs, ys = zip(*coord) #create lists of x and y values
    
    plt.figure()
    plt.plot(xs,ys) 
    plt.show() # if you need...
    
    0 讨论(0)
  • 2021-02-05 09:11

    Another way to draw a polygon is this:

    import PIL.ImageDraw as ImageDraw
    import PIL.Image as Image
    
    image = Image.new("RGB", (640, 480))
    
    draw = ImageDraw.Draw(image)
    
    # points = ((1,1), (2,1), (2,2), (1,2), (0.5,1.5))
    points = ((100, 100), (200, 100), (200, 200), (100, 200), (50, 150))
    draw.polygon((points), fill=200)
    
    image.show()
    

    Note that you need to install the pillow library. Also, I scaled up your coordinates by the factor of 100 so that we can see the polygon on the 640 x 480 screen.

    Hope this helps.

    0 讨论(0)
  • 2021-02-05 09:11
    import numpy as np
    import matplotlib.pyplot as plt
    from matplotlib.patches import Polygon
    
    y = np.array([[1,1], [2,1], [2,2], [1,2], [0.5,1.5]])
    
    p = Polygon(y, facecolor = 'k')
    
    fig,ax = plt.subplots()
    
    ax.add_patch(p)
    ax.set_xlim([0,3])
    ax.set_ylim([0,3])
    plt.show()
    
    0 讨论(0)
提交回复
热议问题