"""Utilidades para la visualización de datos"""
from pathlib import Path
from typing import List, Union
import defusedxml.ElementTree as ET
[documentos]def tema_altair():
"""Un tema de Altair. Colores, dimensiones, tamaño de ticks, de etiquetas, de leyenda.
Returns
-------
tema : Dict
Un diccionario con las especificaciones del tema.
"""
axisColor = "#282828"
markColor = "#282828"
backgroundColor = "#FFFAFA"
font = "Helvetica"
labelfont = "Helvetica"
sourcefont = "Helvetica"
gridColor = "#C9C9C9"
axisLabelSize = 14
return {
"width": 600,
"height": 400,
"autosize": "pad",
"config": {
"padding": 10,
"geoshape": {
"fill": "#D9D9D6",
"stroke": "#2B3E4B",
"strokeWidth": 0.5,
},
"arc": {"fill": markColor,},
"area": {"fill": markColor,},
"axisBand": {"grid": False,},
"axisBottom": {
"domain": False,
"domainColor": "black",
"domainWidth": 3,
"grid": True,
"gridColor": gridColor,
"gridWidth": 1,
"labelFontSize": axisLabelSize,
"labelFont": labelfont,
"labelPadding": 8,
"labelAngle": 0,
"tickColor": axisColor,
"tickSize": 10,
"titleFontSize": 16,
"titlePadding": 10,
"titleFont": font,
"title": "",
},
"axisLeft": {
"domainColor": axisColor,
"domainWidth": 1,
"gridColor": gridColor,
"gridWidth": 1,
"labelFontSize": axisLabelSize,
"labelFont": labelfont,
"labelPadding": 8,
"tickColor": axisColor,
"tickSize": 10,
"tickCount": 10,
"ticks": True,
"titleFontSize": 18,
"titlePadding": 10,
"titleFont": font,
"titleAngle": 0,
"titleX": -70,
"titleY": -18,
"titleAnchor": "start",
},
"axisRight": {
"domainColor": axisColor,
"domainWidth": 1,
"gridColor": gridColor,
"gridWidth": 1,
"labelFontSize": axisLabelSize,
"labelFont": labelfont,
"labelPadding": 4,
"tickColor": axisColor,
"tickSize": 10,
"ticks": True,
"titleFontSize": 14,
"titlePadding": 10,
"titleFont": font,
},
"axisTop": {
"domain": False,
"domainColor": "black",
"domainWidth": 3,
"grid": True,
"gridColor": gridColor,
"gridWidth": 1,
"labelFontSize": axisLabelSize,
"labelFont": labelfont,
"labelPadding": 4,
"tickColor": axisColor,
"tickSize": 10,
"titleFontSize": 14,
"titlePadding": 10,
"titleFont": font,
},
"background": backgroundColor,
"group": {"fill": backgroundColor,},
"legend": {
"labelFontSize": 18,
"labelFont": labelfont,
"labelLimit": 500,
"padding": 5,
"symbolSize": 200,
"symbolType": "square",
"titleFontSize": 20,
"titlePadding": 5,
"titleFont": font,
"titleLimit": 400,
},
"line": {
"color": markColor,
"stroke": markColor,
"strokeWidth": 3,
},
"rule": {
"color": markColor,
"stroke": markColor,
"strokeWidth": 3,
},
"tick": {
"color": markColor,
"stroke": markColor,
"strokeWidth": 1,
},
"trail": {
"color": markColor,
"stroke": markColor,
"strokeWidth": 0,
"size": 5,
},
"path": {"stroke": markColor, "strokeWidth": 0.5,},
"point": {"filled": True,},
"rect": {"fill": "#A20C4B", "opacity": 0.3,},
"range": {
"category": [
"#dc0d7a",
"#02a3cd",
"#e4a100",
"#dc0d12",
"#0DDC6F",
"#074a7e",
"#e46800",
"#aa3594",
"#a20c4b",
],
"diverging": [
"#dc0d12",
"#e9686b",
"#fbe1e1",
"#dff4f9",
"#81d1e6",
"#03a3cd",
],
"heatmap": [
"#fff7fd",
"#ffdbf7",
"#ffb9ec",
"#ff91dc",
"#ff67c7",
"#f83faf",
"#ef1d95",
"#e4007c",
],
},
"symbol": {
"opacity": 1,
"shape": "circle",
"size": 40,
"strokeWidth": 1,
},
"style": {
"bar": {"binSpacing": 2, "fill": markColor, "stroke": False,},
"text": {
"font": sourcefont,
"fontSize": 10,
"align": "right",
"fontWeight": 100,
"size": 10,
},
},
"title": {
"anchor": "start",
"fontSize": 28,
"fontWeight": 600,
"font": font,
"offset": 20,
},
"view": {"stroke": False, "padding": 15,},
"header": {
"fontWeight": 400,
"labelFontSize": axisLabelSize,
"labelFont": labelfont,
"titleFontSize": 20,
"titleFont": font,
"title": " ",
"titleBaseline": "bottom",
"titleOffset": -30,
},
},
}
[documentos]def crear_paleta_tableau(
colores: List[str], tipo: str, nombre: str, agregar_a_tableau: bool = False
) -> Union[str, None]:
r"""Tranforma una lista de colores (en formato hex) en una paleta en formato XML para copiar y pegar en Preferences.tps para su uso en tableau. Si el argumento `agregar_a_tableau` es True puedes agregarla directamente con esta función.
Parameters
----------
colores : List[str]
Una lista de colores en formato hex.
tipo : str
Tipo de paleta de colores: "divergente", "regular", o "secuencial".
nombre : str
Nombre de tu paleta de colores. Por ejemplo, "likert - rojo a azul"
agregar_a_tableau : bool, optional
Si es True, esta función busca tu `Preferences.tps` en `~/Documents/My Tableau Repository/` y agrega la paleta para que no tengas que hacerlo manualmente. Por default es False.
Returns
-------
Union[str, None]
La paleta lista en el formato correcto para `Preferences.tps`. Si `agregar_a_tableau` es True, no se regresa la paleta. Se agrega directo a Preferences.tps
Examples
--------
`crear_paleta_tableau()` te da una cadena de caracteres con caracteres especiales (como el \n para saltar líneas o \t para tabs). Asegurate de hacer `print()` el resultado de la función para copiar y pegar en `Preferences.tps`.
Por ejemplo:
>>> import tacosdedatos_utils as tdd
>>> colores_tdd = ['#dc0d7a', '#02a3cd', '#e4a100', '#dc0d12', '#0DDC6F', '#074a7e', '#e46800', '#aa3594', '#a20c4b',]
>>> paleta_nueva = tdd.crear_paleta_tableau(colores = colores_tdd, tipo = 'regular', nombre = 'tacosdedatos - colores principales')
>>> print(paleta_nueva)
<color-palette name="tacosdedatos - colores principales" type="regular">
<color>#dc0d7a</color>
<color>#02a3cd</color>
<color>#e4a100</color>
<color>#dc0d12</color>
<color>#0DDC6F</color>
<color>#074a7e</color>
<color>#e46800</color>
<color>#aa3594</color>
<color>#a20c4b</color>
</color-palette>
"""
tipos_de_paletas = ["regular", "secuencial", "divergente"]
if tipo not in tipos_de_paletas:
raise TypeError(
f"Las paletas pueden ser solo `regular`, `secuencial`, or `divergente`, tu escogiste: {tipo}"
)
if tipo == "secuencial":
tipo = "ordered-sequential"
if tipo == "divergente":
tipo = "ordered-divergent"
lista_de_colores = [f"\t<color>{color}</color>\n" for color in colores]
colores_de_la_paleta = "".join(lista_de_colores)
paleta = f'<color-palette name="{nombre}" type="{tipo}">\n{colores_de_la_paleta}</color-palette>\n'
if agregar_a_tableau:
repo_tableau = Path.home() / "Documents/My Tableau Repository/"
if repo_tableau.exists():
arbol = ET.parse(repo_tableau / "Preferences.tps")
raiz = arbol.getroot()
preferences = raiz[0]
nueva_paleta = ET.fromstring(paleta)
preferences.append(nueva_paleta)
arbol.write(repo_tableau / "Preferences.tps")
else:
raise OSError(
f"No encontramos la carpeta {str(repo_tableau)} asegurate que exista y tengas acceso a ella."
)
return None
else:
return paleta