Visualization Recommendation

Visualization Recommendation#

In these examples, we use Draco to recommend visualizations based on partial inputs.

from pprint import pprint

from draco import Draco, answer_set_to_dict

d = Draco()
from IPython.display import display
from vega_datasets import data

from draco.renderer import AltairRenderer

# Setting up renderer and demo data
renderer = AltairRenderer()
weather_data = data.seattle_weather()

Histogram#

In this example, we tell Draco to show a binned chart. A possible visualization is a tick plot but because the tick marks would overlap, Draco adds an additional count encoding.

import importlib.resources as pkg_resources

import draco.asp.examples as examples

hist_spec = pkg_resources.read_text(examples, "histogram.lp")

print("INPUT:")
print(hist_spec)

print("OUTPUT:")
model = next(d.complete_spec(hist_spec))
spec = answer_set_to_dict(model.answer_set)
pprint(spec)
display(renderer.render(spec=spec, data=weather_data))

print("VIOLATED PREFERENCES:")
pprint(d.count_preferences(str(model)))
INPUT:
attribute(number_rows,root,100).

entity(field,root,(f,0)).
attribute((field,name),(f,0),temp_max).
attribute((field,type),(f,0),number).
attribute((field,unique),(f,0),100).

entity(view,root,(v,0)).

entity(mark,(v,0),(m,0)).
entity(encoding,(m,0),(e,0)).
attribute((encoding,field),(e,0),temp_max).
attribute((encoding,binning),(e,0),10).

#show entity/3.
#show attribute/3.

OUTPUT:
{'field': [{'name': 'temp_max', 'type': 'number', 'unique': 100}],
 'number_rows': 100,
 'task': 'summary',
 'view': [{'coordinates': 'cartesian',
           'mark': [{'encoding': [{'binning': 10,
                                   'channel': 'y',
                                   'field': 'temp_max'},
                                  {'aggregate': 'count', 'channel': 'x'}],
                     'type': 'bar'}],
           'scale': [{'channel': 'y', 'type': 'linear'},
                     {'channel': 'x', 'type': 'linear', 'zero': 'true'}]}]}
/tmp/ipykernel_4469/2067865367.py:5: DeprecationWarning: read_text is deprecated. Use files() instead. Refer to https://importlib-resources.readthedocs.io/en/latest/using.html#migrating-from-legacy for migration advice.
  hist_spec = pkg_resources.read_text(examples, "histogram.lp")
VIOLATED PREFERENCES:
defaultdict(<class 'int'>,
            {'aggregate': 1,
             'aggregate_count': 1,
             'bin': 1,
             'c_d_no_overlap_bar': 1,
             'cartesian_coordinate': 1,
             'encoding': 2,
             'encoding_field': 1,
             'linear_scale': 2,
             'linear_x': 1,
             'linear_y': 1,
             'summary_bar': 1})

Scatterplot#

In this example, we tell Draco to show two continuous fields. The most effective visualization is a scatterplot.

scatter_spec = pkg_resources.read_text(examples, "scatter.lp")

print("INPUT:")
print(scatter_spec)

print("OUTPUT:")
model = next(d.complete_spec(scatter_spec))
spec = answer_set_to_dict(model.answer_set)
pprint(spec)
display(renderer.render(spec=spec, data=weather_data))

print("VIOLATED PREFERENCES:")
pprint(d.count_preferences(str(model)))
/tmp/ipykernel_4469/782999388.py:1: DeprecationWarning: read_text is deprecated. Use files() instead. Refer to https://importlib-resources.readthedocs.io/en/latest/using.html#migrating-from-legacy for migration advice.
  scatter_spec = pkg_resources.read_text(examples, "scatter.lp")
INPUT:
attribute(number_rows,root,100).

entity(field,root,f0).
attribute((field,name),f0,temp_max).
attribute((field,type),f0,number).

entity(field,root,f1).
attribute((field,name),f1,precipitation).
attribute((field,type),f1,number).

entity(view,root,v0).

entity(mark,v0,m).
entity(encoding,m,e0).
attribute((encoding,field),e0,temp_max).
entity(encoding,m,e1).
attribute((encoding,field),e1,precipitation).

#show entity/3.
#show attribute/3.

OUTPUT:
{'field': [{'name': 'temp_max', 'type': 'number'},
           {'name': 'precipitation', 'type': 'number'}],
 'number_rows': 100,
 'task': 'summary',
 'view': [{'coordinates': 'cartesian',
           'mark': [{'encoding': [{'channel': 'x', 'field': 'temp_max'},
                                  {'channel': 'y', 'field': 'precipitation'}],
                     'type': 'point'}],
           'scale': [{'channel': 'x', 'type': 'linear', 'zero': 'true'},
                     {'channel': 'y', 'type': 'linear', 'zero': 'true'}]}]}
VIOLATED PREFERENCES:
defaultdict(<class 'int'>,
            {'c_c_point': 1,
             'cartesian_coordinate': 1,
             'encoding': 2,
             'encoding_field': 2,
             'linear_scale': 2,
             'linear_x': 1,
             'linear_y': 1,
             'summary_point': 1})