Genero un gráfico de líneas en Altair. Me gustaría controlar qué líneas están "encima" de la pila de líneas. En mi ejemplo aquí, deseo que la línea roja esté en la parte superior (fecha más reciente) y luego descienda hasta la amarilla (fecha más antigua) para estar en la parte inferior.
Traté de controlar esto con el parámetro de sort de alt.Color pero independientemente de sort='ascending' o sort='descending' el orden de la superposición de líneas no cambiará.
¿Cómo puedo controlar esto? Esperaba poder hacer esto sin ordenar mi marco de datos de origen.
data = [{'review_date': dt.date(year=2022, month=2, day=24), 'a':19, 'b':17, 'c':12, 'd':8}, {'review_date': dt.date(year=2022, month=2, day=23), 'a':20, 'b':16, 'c':14, 'd':8}, {'review_date': dt.date(year=2022, month=2, day=22), 'a':22, 'b':16, 'c':14, 'd':10}, {'review_date': dt.date(year=2022, month=2, day=21), 'a':14, 'b':13, 'c':12, 'd':5},] df = pd.DataFrame(data).melt(id_vars=['review_date'], value_name='price', var_name='contract') df.review_date = pd.to_datetime(df.review_date) domain = df.review_date.unique() range_ = ['red', 'blue', 'gray', 'yellow'] alt.Chart(df, title='foo').mark_line().encode( x=alt.X('contract:N'), y=alt.Y('price:Q',scale=alt.Scale(zero=False)), color=alt.Color('review_date:O', sort="ascending", scale=alt.Scale(domain=domain, range=range_) ) ).interactive()De forma predeterminada, las marcas gráficas se trazan en el orden en que aparecen en el marco de datos (como notó), lo que significa que los últimos elementos en el marco de datos se trazarán en último lugar y terminarán en la parte superior del gráfico (llamada la "capa" más alta o el "orden z" más alto):
import pandas as pd import altair as alt df = pd.DataFrame({ 'a': [1, 2, 1, 2], 'b': [1.1, 2.1, 1.0, 2.2], 'c': ['point1', 'point1', 'point2', 'point2'] }) alt.Chart(df).mark_circle(size=1000).encode( x='a', y='b', color='c' ) Cuando establece el parámetro de sort de la codificación de color, no está cambiando el orden z de los puntos, solo está cambiando el orden en el que se les asigna un color. En el diagrama a continuación, "point2" todavía está en la parte superior, pero ahora es azul en lugar de naranja:
alt.Chart(df).mark_circle(size=1000).encode( x='a', y='b', color=alt.Color('c', sort='descending') ) Si quisiéramos cambiar el orden z para que "punto1" esté en la parte superior, tendríamos que especificar esto con la codificación de order :
alt.Chart(df).mark_circle(size=1000).encode( x='a', y='b', color='c', order=alt.Order('c', sort='descending') ) Sin embargo, como puede leer en la documentación de Vega-Lite, la codificación de order tiene un comportamiento especial para las marcas apiladas y de ruta, incluida la marca de línea, donde controla el orden en que los puntos se conectan en una línea en lugar de su orden z/ estratificación
Por lo tanto, creo que la única forma de lograr el comportamiento deseado es ordenar esa columna. Puede hacer esto durante la construcción del gráfico:
alt.Chart(df).mark_line(size=10).encode( x='a', y='b', color='c' ) alt.Chart(df.sort_values('c', ascending=False)).mark_line(size=10).encode( x='a', y='b', color='c' )