Crear una imagen a partir de un dataframe usando Python

publicado por: Anonymous

estoy intentando crear una imagen de un tamaño especifico de pixeles y dibujar en ella varias trayectorias que tengo ordenadas en un dataframe por coordenadas x y. Un ejemplo de como luce el dataframe con 2 trayectorias seria asi:

In [60]: df
Out[60]: 
TRACK_ID     x            y                        
1          16.130       8.993
1          15.817       8.699
1          16.076       8.712
1          16.176       8.191
1          16.486       8.106
2          16.308       8.500
2          16.270       8.441
2          16.042       8.474
2          15.966       8.487
2          15.882       8.431
2          15.869       8.419

Después, uso PIL para generar la imagen:

from PIL import Image
from PIL import ImageDraw
img = Image.new("RGB", (512,512), "black")
draw = ImageDraw.Draw(img)

coords = ['x','y']
dotSize = 2

for (x,y) in coords:
    draw.line([x,y,x+dotSize-1,y+dotSize-1], fill="red")

img.show()

Esto funciona bien para puntos (x,y) pero debo ingresar uno por uno, Como puedo hacer para ingresar mis columnas completas como trayectorias independientes? Existe una forma mas simple de pasar mis columnas a una imagen binaria? Gracias

solución

Puedes usar pandas.groupby para obtener cada trayectoria en función del valor de la columna TRACK_ID. Hecho esto solo tienes que iterar sobre el objeto groupby y por cada grupo crear un iterable de tuplas (x, y) para pasárselo a draw.line. Esto ultimo puedes hacerlo con zip.

Si quieres, puede crear otro iterable para dibujar cada grupo con un color diferente. Una opción muy simple es crear un mapa de colores cíclico usando itertool.cycle. Puedes usar valores RGB o HSL para definir los colores, no obstante, suele ser más simple usar nombres de colores HTML(mas información en http://pillow.readthedocs.io/en/3.1.x/reference/ImageColor.html#color-names)

Por ejemplo, vamos a crear un dataframe similar al tuyo (se van a distanciar más los puntos para que sea más descriptivo) y vamos a crear una linea para cada trayectoria de un color diferente:

import itertools
import pandas as pd
from PIL import Image
from PIL import ImageDraw


data = {"TRACK_ID": [1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4],
        "x": [10, 75, 50, 300, 400, 12, 17, 27, 30, 45, 40, 15, 65, 400, 19, 45, 234],
        "Y": [10, 75, 50, 300, 500, 10, 105, 200, 100, 305, 420, 17, 47, 176, 20, 165, 375]}

df = pd.DataFrame(data)
df.set_index("TRACK_ID", inplace = True)


# Lo anterior es solo para crear un DataFraem como el tuyo,
# lo importante es lo siguiente:
tracks = df.groupby("TRACK_ID")

img = Image.new("RGB", (512,512), "black")
draw = ImageDraw.Draw(img)
colors = itertools.cycle(("Red", "Chartreuse", "DarkOrange", "DarkMagenta"))

for t, group in tracks:
    coords = tuple(zip(group.x, group.Y))
    draw.line(coords, width=2, fill=next(colors))


img.show()

Salida:

introducir la descripción de la imagen aquí

Los colores también los puedes definir en un diccionario, siendo la clave cada valor de TRACK_ID, de forma que puedes definir con precisión con que color se dibuja cada trayectoria.

Respondido por: Anonymous

Leave a Reply

Your email address will not be published. Required fields are marked *