pygooglechart y tus ciudades en 11870.com
Por Luis Peralta
El tener una API en 11870.com permite, entre otras cosas, el prototipado rápido de chorradas varias sin mucho esfuerzo. Así que hoy me ha dado por probar un poco otra API: Google Chart API (API de gráficas de Google) y que menos que explotar algún dato de los que hay en 11870.com. Ya se sabe, una imagen vale más que mil palabras, así que me he decidido a pintar las ciudades donde tengo sitios guardados.
Podría haber manejado a pelo la API de Google pero, puestos a probar, me he tirado a Python Google Chart que ofrece una interfaz para Python bastante cómoda. Lo primero que ha habido que hacer es descargar la lista de mis sitios:
import httplib2
import feedparser
def get_oos_entries(slug):
user = "luis@XXXXXXX"
key = "XXXXXXX"
base_url = OOSURL + "/sites/" + slug
entries = []
h = httplib2.Http()
h.add_credentials(user, key)
next_url = [base_url]
while len(next_url) == 1:
base_url = next_url[0]
r, c = h.request(base_url)
feed = feedparser.parse(c)
entries.extend(feed.entries)
next_url = [i.href for i in feed.feed.links if i.rel == 'next']
return entries
La lógica puede parecer un poco difusa, pero es simplemente porque el feed de resultados de nuestros sitios está paginado y los necesitamos todos. El cómo conseguir la key está documentado en 11870.com API authentication. Una vez con los sitios, tenemos que saber cuántos sitios hay por cada localidad o área geográfica:
from operator import itemgetter
from itertools import groupby
def do_chart_input(entries, field, other_threshold=None):
f = itemgetter(field)
lentries = [entry for entry in entries if entry.get(field, None)]
sorted_entries = sorted(lentries, key=f)
res = {}
others = 0
for k, g in groupby(sorted_entries, f):
num = len(map(f, g))
if other_threshold is not None and num / float(len(lentries)) < other_threshold:
others += num
else:
key = k + u' (' + str(num) + ')'
res[key] = num
if other_threshold is not None:
res['Otros (' + str(others) + ')'] = others
return res
A este método se le pasan las entries
obtenidas con get_oos_entries
, el
campo sobre el que realizar la agrupación y si queremos que aquellas
agrupaciones que no superen un cierto umbral se agrupen bajo un Otros
. En el
caso de mis ciudades, hay un montón de ellas donde sólo tengo un sitio, por lo
que la gráfica salía muy muy fea si no aplicaba el filtro con umbral. El
parámetro field
sirve para determinar sobre qué elemento de cada entrada
realizamos la agrupación y así conseguimos que el método sea lo
suficientemente genérico como para calcular los datos sobre cualquier tipo de
área (país, ciudad, barrio, etc…). El cuerpo principal de nuestro programita
sería tal que así:
if __name__ == '__main__':
entries = get_oos_entries('peralta')
res = do_chart_input(entries, 'oos_locality', 0.03)
chart = PieChart2D(600,375)
chart.add_data(res.values())
chart.set_pie_labels([i.encode('utf-8') for i in res.keys()])
chart.set_title('mis ciudades en 11870.com')
chart.download("/tmp/x.png")
Y el resultado:
Si quisiéramos pintar los barrios de manu, modificariamos el cuerpo principal tal que:
entries = get_oos_entries('manueltxo')
res = do_chart_input(entries, 'oos_subdependentlocality', 0.03)
Y el resultado:
De aquí a hacer una interfaz web para mostrar estas imágenes a partir de cualquier usuario hay 15 minutos, pero se queda como ejercicio ;)