We will try to reproduce this example from the Altair gallery, but with lazily fetching data as the user interacts with the slider. To keep ourselves honest, we'll be putting the data in a SQLite database.
First, let's show the original example, without any modifications:
import altair as alt
from vega_datasets import data
source = data.population.url
pink_blue = alt.Scale(domain=('Male', 'Female'),
range=["steelblue", "salmon"])
slider = alt.binding_range(min=1900, max=2000, step=10)
select_year = alt.selection_single(name="year", fields=['year'],
bind=slider, init={'year': 2000})
alt.Chart(source).mark_bar().encode(
x=alt.X('sex:N', title=None),
y=alt.Y('people:Q', scale=alt.Scale(domain=(0, 12000000))),
color=alt.Color('sex:N', scale=pink_blue),
column='age:O'
).properties(
width=20
).add_selection(
select_year
).transform_calculate(
"sex", alt.expr.if_(alt.datum.sex == 1, "Male", "Female")
).transform_filter(
select_year
).configure_facet(
spacing=8
)
We begin our lazy-fetching example by downloading the data and putting it into a SQLite database:
import sqlalchemy
dbfile = 'population.db'
engine = sqlalchemy.create_engine(f'sqlite:///{dbfile}')
import pandas as pd
df = pd.read_json(data.population.url)
df.to_sql('pop', engine, if_exists='replace')
Now, let's create an ibis connection to this database and verify that the data is there:
import ibis
import warnings
try:
# ibis version >= 1.4
from ibis.backends import sqlite as ibis_sqlite
except ImportError as msg:
# ibis version < 1.4
warnings.warn(str(msg))
from ibis import sqlite as ibis_sqlite
connection = ibis_sqlite.connect(dbfile)
connection.list_tables()
We can use inspect the data using this ibis connection:
pop = connection.table('pop')
pop.head().execute()
We are now ready to make an interactive plot using this database connection.
We can reuse the same objects for pink_blue
, slider
, and select_year
, as they are independent of the data source.
The Chart
specifiation is completely identical, except that instead of the pandas dataframe,
we supply it with the Ibis sqlite connection:
# import ibis_vega_transform
# alt.Chart(pop).mark_bar().encode(
# x=alt.X('sex:N', title=None),
# y=alt.Y('people:Q', scale=alt.Scale(domain=(0, 12000000))),
# color=alt.Color('sex:N', scale=pink_blue),
# column='age:O'
# ).properties(
# width=20
# ).add_selection(
# select_year
# ).transform_calculate(
# "sex", alt.expr.if_(alt.datum.sex == 1, "Male", "Female")
# ).transform_filter(
# select_year
# ).configure_facet(
# spacing=8
# )