!pip install sparqlwrapper
!pip install mako
%matplotlib inline
import pandas as pd
import json
from SPARQLWrapper import SPARQLWrapper, JSON
from mako.template import Template

Parámetros

param_top_n_occupations = 20
param_country_qid = "Q142"
param_born_after = "1963"
param_born_before = "1982"
param_wikipedia = "es"
def get_sparql_dataframe(service, query):
    """
    Helper function to convert SPARQL results into a Pandas data frame.
    """
    sparql = SPARQLWrapper(service)
    sparql.setQuery(query)
    sparql.setReturnFormat(JSON)
    result = sparql.query()

    processed_results = json.load(result.response)
    cols = processed_results['head']['vars']

    out = []
    for row in processed_results['results']['bindings']:
        item = []
        for c in cols:
            item.append(row.get(c, {}).get('value'))
        out.append(item)

    return pd.DataFrame(out, columns=cols)
rq_template = """
SELECT ?sexoLabel ?ocupacionLabel (COUNT(?persona) AS ?cantidad) WHERE {

  ?persona wdt:P31 wd:Q5;
         wdt:P21 ?sexo;
         wdt:P27 wd:${country};
         wdt:P106 ?ocupacion.
  ?persona p:P569/psv:P569 ?birth_date_node .
  ?birth_date_node wikibase:timeValue ?birth_date .
  ?url a schema:Article;
         schema:about ?persona;         
         schema:isPartOf  <https://${wikipedia}.wikipedia.org/> 

  FILTER (year(?birth_date) >= ${born_after} && year(?birth_date) < ${born_before}) .                      
  SERVICE wikibase:label { bd:serviceParam wikibase:language "es,en". }
}
GROUP BY ?ocupacionLabel ?sexoLabel 
ORDER BY DESC(?cantidad) ?ocupacionLabel ?sexoLabel 
"""

vars = {
    "country": param_country_qid,
    "born_after": param_born_after,
    "born_before": param_born_before,
    "wikipedia": param_wikipedia
    }

t = Template(rq_template)
rq = t.render(**vars)
#Ejecuta la consulta y obtiene un dataframe
wds = "https://query.wikidata.org/sparql"
df = get_sparql_dataframe(wds, rq)
df.cantidad = pd.to_numeric(df.cantidad)
print(f"Filas: {df.shape[0]}  Columnas: {df.shape[1]}")
df.head()
# Recorre los resultados que contienen una línea por sexo y profesión 
# y genera un dataframe nuevo con columnas para cada sexo y filas para cada profesión
proc = pd.DataFrame()

for o in df['ocupacionLabel'].unique():
    for s in df['sexoLabel'].unique():
        c = df.loc[(df['sexoLabel'] == s) & (df['ocupacionLabel'] == o), 'cantidad']
        if len(c) > 0:
            proc.loc[o,s] = int(c)
        else:
            proc.loc[o,s] = 0

# Agrega una columna con la suma de todas las columnas
proc['sum'] = proc[list(proc.columns)].sum(axis=1)

proc.head(param_top_n_occupations)
#obtiene las profesiones a graficar tomando las n con más elementos
gr = proc.nlargest(n=param_top_n_occupations, columns=['sum'])

Gráfico

import matplotlib
matplotlib.rcParams['figure.figsize'] = 12,10
gr.drop(['sum'], axis=1).plot(kind="barh",stacked=True)

Gráfico sin futbolistas

gr.drop(['futbolista', 'entrenador de fútbol'], axis=0, errors="ignore").drop(['sum'], axis=1).plot(kind="barh",stacked=True)