def test_layer_errors(): toplevel_chart = alt.Chart("data.txt").mark_point().configure_legend( columns=2) facet_chart1 = alt.Chart("data.txt").mark_point().encode(facet="row:Q") facet_chart2 = alt.Chart("data.txt").mark_point().facet("row:Q") repeat_chart = alt.Chart("data.txt").mark_point().repeat(["A", "B", "C"]) simple_chart = alt.Chart("data.txt").mark_point() with pytest.raises(ValueError) as err: toplevel_chart + simple_chart assert str(err.value).startswith( 'Objects with "config" attribute cannot be used within LayerChart.') with pytest.raises(ValueError) as err: repeat_chart + simple_chart assert str(err.value) == "Repeat charts cannot be layered." with pytest.raises(ValueError) as err: facet_chart1 + simple_chart assert str(err.value) == "Faceted charts cannot be layered." with pytest.raises(ValueError) as err: alt.layer(simple_chart) + facet_chart2 assert str(err.value) == "Faceted charts cannot be layered."
def test_repeat(): # wrapped repeat chart1 = (alt.Chart("data.csv").mark_point().encode( x=alt.X(alt.repeat(), type="quantitative"), y="y:Q", ).repeat(["A", "B", "C", "D"], columns=2)) dct1 = chart1.to_dict() assert dct1["repeat"] == ["A", "B", "C", "D"] assert dct1["columns"] == 2 assert dct1["spec"]["encoding"]["x"]["field"] == {"repeat": "repeat"} # explicit row/col repeat chart2 = (alt.Chart("data.csv").mark_point().encode( x=alt.X(alt.repeat("row"), type="quantitative"), y=alt.Y(alt.repeat("column"), type="quantitative"), ).repeat(row=["A", "B", "C"], column=["C", "B", "A"])) dct2 = chart2.to_dict() assert dct2["repeat"] == { "row": ["A", "B", "C"], "column": ["C", "B", "A"] } assert "columns" not in dct2 assert dct2["spec"]["encoding"]["x"]["field"] == {"repeat": "row"} assert dct2["spec"]["encoding"]["y"]["field"] == {"repeat": "column"}
def test_facet_basic(): # wrapped facet chart1 = (alt.Chart("data.csv").mark_point().encode( x="x:Q", y="y:Q", ).facet("category:N", columns=2)) dct1 = chart1.to_dict() assert dct1["facet"] == alt.Facet("category:N").to_dict() assert dct1["columns"] == 2 assert dct1["data"] == alt.UrlData("data.csv").to_dict() # explicit row/col facet chart2 = (alt.Chart("data.csv").mark_point().encode( x="x:Q", y="y:Q", ).facet(row="category1:Q", column="category2:Q")) dct2 = chart2.to_dict() assert dct2["facet"]["row"] == alt.Facet("category1:Q").to_dict() assert dct2["facet"]["column"] == alt.Facet("category2:Q").to_dict() assert "columns" not in dct2 assert dct2["data"] == alt.UrlData("data.csv").to_dict()
def test_consolidate_InlineData(): data = alt.InlineData(values=[{ "a": 1, "b": 1 }, { "a": 2, "b": 2 }], format={"type": "csv"}) chart = alt.Chart(data).mark_point() with alt.data_transformers.enable(consolidate_datasets=False): dct = chart.to_dict() assert dct["data"]["format"] == data.format assert dct["data"]["values"] == data.values with alt.data_transformers.enable(consolidate_datasets=True): dct = chart.to_dict() assert dct["data"]["format"] == data.format assert list(dct["datasets"].values())[0] == data.values data = alt.InlineData(values=[], name="runtime_data") chart = alt.Chart(data).mark_point() with alt.data_transformers.enable(consolidate_datasets=False): dct = chart.to_dict() assert dct["data"] == data.to_dict() with alt.data_transformers.enable(consolidate_datasets=True): dct = chart.to_dict() assert dct["data"] == data.to_dict()
def test_subcharts_different_data(method, data): func = getattr(alt, method) point = alt.Chart(data).mark_point().encode(x="x:Q", y="y:Q") otherdata = alt.Chart("data.csv").mark_point().encode(x="x:Q", y="y:Q") nodata = alt.Chart().mark_point().encode(x="x:Q", y="y:Q") chart1 = func(point, otherdata) assert chart1.data is alt.Undefined assert getattr(chart1, method)[0].data is data chart2 = func(point, nodata) assert chart2.data is alt.Undefined assert getattr(chart2, method)[0].data is data
def test_selection(): # test instantiation of selections interval = alt.selection_interval(name="selec_1") assert interval.param.select.type == "interval" assert interval.name == "selec_1" single = alt.selection_single(name="selec_2") assert single.param.select.type == "point" assert single.name == "selec_2" multi = alt.selection_multi(name="selec_3") assert multi.param.select.type == "point" assert multi.name == "selec_3" # test adding to chart chart = alt.Chart().add_selection(single) chart = chart.add_selection(multi, interval) assert set(x.name for x in chart.params) == {"selec_1", "selec_2", "selec_3"} # test logical operations assert isinstance(single & multi, alt.SelectionPredicateComposition) assert isinstance(single | multi, alt.SelectionPredicateComposition) assert isinstance(~single, alt.SelectionPredicateComposition) assert "and" in (single & multi).to_dict().keys() assert "or" in (single | multi).to_dict().keys() assert "not" in (~single).to_dict().keys() # test that default names increment (regression for #1454) sel1 = alt.selection_single() sel2 = alt.selection_multi() sel3 = alt.selection_interval() names = {s.name for s in (sel1, sel2, sel3)} assert len(names) == 3
def test_geo_interface_empty_feature_collection(): geom = {"type": "FeatureCollection", "features": []} feat = geom_obj(geom) with alt.data_transformers.enable(consolidate_datasets=False): spec = alt.Chart(feat).mark_geoshape().to_dict() assert spec["data"]["values"] == []
def test_geo_interface_feature_collection_gdf(): geom = { "bbox": (19.89, -26.82, 29.43, -17.66), "features": [{ "bbox": (19.89, -26.82, 29.43, -17.66), "geometry": { "coordinates": [[[6.90, 53.48], [5.98, 51.85], [6.07, 53.51], [6.90, 53.48]]], "type": "Polygon", }, "id": "49", "properties": { "continent": "Africa", "gdp_md_est": 35900.0, "id": "BWA", "iso_a3": "BWA", "name": "Botswana", "pop_est": 2214858, }, "type": "Feature", }], "type": "FeatureCollection", } feat = geom_obj(geom) with alt.data_transformers.enable(consolidate_datasets=False): spec = alt.Chart(feat).mark_geoshape().to_dict() assert spec["data"]["values"][0]["id"] == "BWA"
def test_compound_add_selections(charttype): base = alt.Chart("data.csv").mark_point() selection = alt.selection_single() chart1 = charttype(base.add_selection(selection), base.add_selection(selection)) chart2 = charttype(base, base).add_selection(selection) assert chart1.to_dict() == chart2.to_dict()
def basic_chart(): data = pd.DataFrame({ "a": ["A", "B", "C", "D", "E", "F", "G", "H", "I"], "b": [28, 55, 43, 91, 81, 53, 19, 87, 52], }) return alt.Chart(data).mark_bar().encode(x="a", y="b")
def test_facet_parse_data(): data = pd.DataFrame({"x": range(5), "y": range(5), "row": list("abcab")}) chart = (alt.Chart(data).mark_point().encode(x="x", y="y:O").facet( row="row", column="column:O")) with alt.data_transformers.enable(consolidate_datasets=False): dct = chart.to_dict() assert "values" in dct["data"] assert "data" not in dct["spec"] assert dct["facet"] == { "column": { "field": "column", "type": "ordinal" }, "row": { "field": "row", "type": "nominal" }, } with alt.data_transformers.enable(consolidate_datasets=True): dct = chart.to_dict() assert "datasets" in dct assert "name" in dct["data"] assert "data" not in dct["spec"] assert dct["facet"] == { "column": { "field": "column", "type": "ordinal" }, "row": { "field": "row", "type": "nominal" }, }
def test_geo_interface_serializing_arrays_tuples(): import array as arr geom = { "bbox": arr.array("d", [1, 2, 3, 4]), "geometry": { "coordinates": [ tuple(( tuple((6.90, 53.48)), tuple((5.98, 51.85)), tuple((6.07, 53.51)), tuple((6.90, 53.48)), )) ], "type": "Polygon", }, "id": 27, "properties": {}, "type": "Feature", } feat = geom_obj(geom) with alt.data_transformers.enable(consolidate_datasets=False): spec = alt.Chart(feat).mark_geoshape().to_dict() assert spec["data"]["values"]["geometry"]["coordinates"][0][0] == [ 6.9, 53.48 ]
def _make_chart_type(chart_type): data = pd.DataFrame({ "x": [28, 55, 43, 91, 81, 53, 19, 87], "y": [43, 91, 81, 53, 19, 87, 52, 28], "color": list("AAAABBBB"), }) base = (alt.Chart(data).mark_point().encode( x="x", y="y", color="color", )) if chart_type in ["layer", "hconcat", "vconcat", "concat"]: func = getattr(alt, chart_type) return func(base.mark_square(), base.mark_circle()) elif chart_type == "facet": return base.facet("color") elif chart_type == "facet_encoding": return base.encode(facet="color") elif chart_type == "repeat": return base.encode(alt.X(alt.repeat(), type="quantitative")).repeat(["x", "y"]) elif chart_type == "chart": return base else: raise ValueError( "chart_type='{}' is not recognized".format(chart_type))
def test_chart_operations(): data = pd.DataFrame({ "x": pd.date_range("2012", periods=10, freq="Y"), "y": range(10), "c": list("abcabcabca"), }) chart1 = alt.Chart(data).mark_line().encode(x="x", y="y", color="c") chart2 = chart1.mark_point() chart3 = chart1.mark_circle() chart4 = chart1.mark_square() chart = chart1 + chart2 + chart3 assert isinstance(chart, alt.LayerChart) assert len(chart.layer) == 3 chart += chart4 assert len(chart.layer) == 4 chart = chart1 | chart2 | chart3 assert isinstance(chart, alt.HConcatChart) assert len(chart.hconcat) == 3 chart |= chart4 assert len(chart.hconcat) == 4 chart = chart1 & chart2 & chart3 assert isinstance(chart, alt.VConcatChart) assert len(chart.vconcat) == 3 chart &= chart4 assert len(chart.vconcat) == 4
def test_geo_interface_polygon_feature(): geom = { "coordinates": [[(0, 0), (0, 2), (2, 2), (2, 0), (0, 0)]], "type": "Polygon", } feat = geom_obj(geom) with alt.data_transformers.enable(consolidate_datasets=False): spec = alt.Chart(feat).mark_geoshape().to_dict() assert spec["data"]["values"]["type"] == "Feature"
def test_add_selection(): selections = [ alt.selection_interval(), alt.selection_single(), alt.selection_multi(), ] chart = (alt.Chart().mark_point().add_selection( selections[0]).add_selection(selections[1], selections[2])) expected = [s.param for s in selections] assert chart.params == expected
def test_selection_to_dict(): brush = alt.selection(type="interval") # test some value selections # Note: X and Y cannot have conditions alt.Chart("path/to/data.json").mark_point().encode( color=alt.condition(brush, alt.ColorValue("red"), alt.ColorValue("blue")), opacity=alt.condition(brush, alt.value(0.5), alt.value(1.0)), text=alt.condition(brush, alt.TextValue("foo"), alt.value("bar")), ).to_dict() # test some field selections # Note: X and Y cannot have conditions # Conditions cannot both be fields alt.Chart("path/to/data.json").mark_point().encode( color=alt.condition(brush, alt.Color("col1:N"), alt.value("blue")), opacity=alt.condition(brush, "col1:N", alt.value(0.5)), text=alt.condition(brush, alt.value("abc"), alt.Text("col2:N")), size=alt.condition(brush, alt.value(20), "col2:N"), ).to_dict()
def test_chart_infer_types(): data = pd.DataFrame({ "x": pd.date_range("2012", periods=10, freq="Y"), "y": range(10), "c": list("abcabcabca"), }) def _check_encodings(chart): dct = chart.to_dict() assert dct["encoding"]["x"]["type"] == "temporal" assert dct["encoding"]["x"]["field"] == "x" assert dct["encoding"]["y"]["type"] == "quantitative" assert dct["encoding"]["y"]["field"] == "y" assert dct["encoding"]["color"]["type"] == "nominal" assert dct["encoding"]["color"]["field"] == "c" # Pass field names by keyword chart = alt.Chart(data).mark_point().encode(x="x", y="y", color="c") _check_encodings(chart) # pass Channel objects by keyword chart = (alt.Chart(data).mark_point().encode(x=alt.X("x"), y=alt.Y("y"), color=alt.Color("c"))) _check_encodings(chart) # pass Channel objects by value chart = alt.Chart(data).mark_point().encode(alt.X("x"), alt.Y("y"), alt.Color("c")) _check_encodings(chart) # override default types chart = (alt.Chart(data).mark_point().encode(alt.X("x", type="nominal"), alt.Y("y", type="ordinal"))) dct = chart.to_dict() assert dct["encoding"]["x"]["type"] == "nominal" assert dct["encoding"]["y"]["type"] == "ordinal"
def test_facet_parse(): chart = (alt.Chart("data.csv").mark_point().encode(x="x:Q", y="y:Q").facet( row="row:N", column="column:O")) dct = chart.to_dict() assert dct["data"] == {"url": "data.csv"} assert "data" not in dct["spec"] assert dct["facet"] == { "column": { "field": "column", "type": "ordinal" }, "row": { "field": "row", "type": "nominal" }, }
def test_multiple_encodings(args, kwargs): df = pd.DataFrame({"value": [1, 2, 3], "name": ["A", "B", "C"]}) encoding_dct = [ { "field": "value", "type": "quantitative" }, { "field": "name", "type": "nominal" }, ] chart = alt.Chart(df).mark_point().encode(*args, **kwargs) dct = chart.to_dict() assert dct["encoding"]["detail"] == encoding_dct assert dct["encoding"]["tooltip"] == encoding_dct
def test_subcharts_with_same_data(method, data): func = getattr(alt, method) point = alt.Chart(data).mark_point().encode(x="x:Q", y="y:Q") line = point.mark_line() text = point.mark_text() chart1 = func(point, line, text) assert chart1.data is not alt.Undefined assert all(c.data is alt.Undefined for c in getattr(chart1, method)) if method != "concat": op = OP_DICT[method] chart2 = op(op(point, line), text) assert chart2.data is not alt.Undefined assert all(c.data is alt.Undefined for c in getattr(chart2, method))
def test_geo_interface_feature_collection(): geom = { "type": "FeatureCollection", "features": [ { "geometry": { "coordinates": [[[6.90, 53.48], [5.98, 51.85], [6.07, 53.51], [6.90, 53.48]]], "type": "Polygon", }, "id": 27, "properties": { "type": "foo", "id": 1, "geometry": 1 }, "type": "Feature", }, { "geometry": { "coordinates": [[[8.90, 53.48], [7.98, 51.85], [8.07, 53.51], [8.90, 53.48]]], "type": "Polygon", }, "id": 28, "properties": { "type": "foo", "id": 2, "geometry": 1 }, "type": "Feature", }, ], } feat = geom_obj(geom) with alt.data_transformers.enable(consolidate_datasets=False): spec = alt.Chart(feat).mark_geoshape().to_dict() assert spec["data"]["values"][0]["id"] == 1 assert spec["data"]["values"][1]["id"] == 2 assert "coordinates" in spec["data"]["values"][0]["geometry"] assert "coordinates" in spec["data"]["values"][1]["geometry"] assert spec["data"]["values"][0]["type"] == "Feature" assert spec["data"]["values"][1]["type"] == "Feature"
def test_geo_interface_removal_empty_properties(): geom = { "geometry": { "coordinates": [[[6.90, 53.48], [5.98, 51.85], [6.07, 53.51], [6.90, 53.48]]], "type": "Polygon", }, "id": None, "properties": {}, "type": "Feature", } feat = geom_obj(geom) with alt.data_transformers.enable(consolidate_datasets=False): spec = alt.Chart(feat).mark_geoshape().to_dict() assert spec["data"]["values"]["type"] == "Feature"
def test_geo_interface_register_foreign_member(): geom = { "geometry": { "coordinates": [[[6.90, 53.48], [5.98, 51.85], [6.07, 53.51], [6.90, 53.48]]], "type": "Polygon", }, "id": 2, "properties": { "foo": "bah" }, "type": "Feature", } feat = geom_obj(geom) with alt.data_transformers.enable(consolidate_datasets=False): spec = alt.Chart(feat).mark_geoshape().to_dict() with pytest.raises(KeyError): spec["data"]["values"]["id"] assert spec["data"]["values"]["foo"] == "bah"
def test_chart_from_dict(): base = alt.Chart("data.csv").mark_point().encode(x="x:Q", y="y:Q") charts = [ base, base + base, base | base, base & base, base.facet("c:N"), (base + base).facet(row="c:N", data="data.csv"), base.repeat(["c", "d"]), (base + base).repeat(row=["c", "d"]), ] for chart in charts: chart_out = alt.Chart.from_dict(chart.to_dict()) assert type(chart_out) is type(chart) # test that an invalid spec leads to a schema validation error with pytest.raises(jsonschema.ValidationError): alt.Chart.from_dict({"invalid": "spec"})
def test_themes(): chart = alt.Chart("foo.txt").mark_point() with alt.themes.enable("default"): assert chart.to_dict()["config"] == { "view": { "continuousWidth": 400, "continuousHeight": 300 } } with alt.themes.enable("opaque"): assert chart.to_dict()["config"] == { "background": "white", "view": { "continuousWidth": 400, "continuousHeight": 300 }, } with alt.themes.enable("none"): assert "config" not in chart.to_dict()
def test_display_options(): chart = alt.Chart("data.csv").mark_point().encode(x="foo:Q") # check that there are no options by default with check_render_options(): chart.display() # check that display options are passed with check_render_options(embed_options={ "tooltip": False, "renderer": "canvas" }): chart.display("canvas", tooltip=False) # check that above options do not persist with check_render_options(): chart.display() # check that display options augment rather than overwrite pre-set options with alt.renderers.enable(embed_options={ "tooltip": True, "renderer": "svg" }): with check_render_options(embed_options={ "tooltip": True, "renderer": "svg" }): chart.display() with check_render_options(embed_options={ "tooltip": True, "renderer": "canvas" }): chart.display("canvas") # check that above options do not persist with check_render_options(): chart.display()
def chart(): return alt.Chart("data.csv").mark_point()
def chart(): return alt.Chart("data.csv").mark_bar().encode(x="x:Q")
def test_data_property(): data = pd.DataFrame({"x": [1, 2, 3], "y": list("ABC")}) chart1 = alt.Chart(data).mark_point() chart2 = alt.Chart().mark_point().properties(data=data) assert chart1.to_dict() == chart2.to_dict()