Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

KeyError while using Altair with Panel #780

Closed
labdmitriy opened this issue Nov 13, 2019 · 2 comments
Closed

KeyError while using Altair with Panel #780

labdmitriy opened this issue Nov 13, 2019 · 2 comments
Labels
type: bug Something isn't correct or isn't working

Comments

@labdmitriy
Copy link

labdmitriy commented Nov 13, 2019

When I try to use Altair with Panel to show geo map with default data transformer in jupyterlab, I have a KeyError that probably is similar to error in #422.
I've updated altair/vega/panel/jupyter packages to the latest versions before experiments.
The code is the following:

alt.data_transformers.enable('default', max_rows=None)

areas = ['Country', 'Sub-Region', 'Region']
area = pn.widgets.Select(name='Area type:', options=areas)

@pn.depends(area.param.value)
def plot_map(area):
    counter_name = area.lower() + '_count'
    countries = alt.topo_feature(data.world_110m.url, 'countries')
    
    country_map = alt.Chart(countries).mark_geoshape(
    ).encode(
        color=f'{counter_name}:Q',
        tooltip=[
            alt.Tooltip('region:N', title='Region'),
            alt.Tooltip('sub-region:N', title='Sub-Region'),
            alt.Tooltip('answer:N', title='Country'),
            alt.Tooltip(f'{counter_name}:Q', title=f'Questions Count by {area}')
        ]
    ).transform_lookup(
        lookup='id',
        from_=alt.LookupData(merged_stats_df, 'id', merged_stats_df.columns.tolist())
    ).project(
        type='mercator'
    ).properties(
        width=600,
        height=400
    )

    borders = alt.Chart(countries).mark_geoshape(
        fill='white',
        stroke='grey',
        strokeWidth=1
    ).transform_filter(
        datum.id!=10
    ).properties(
        width=600,
        height=400
    )
   
    return (borders + country_map)

pn.Row(
    pn.Column(area),
    plot_map
).servable()

Traceback:

KeyError                                  Traceback (most recent call last)
/opt/conda/lib/python3.6/site-packages/IPython/core/formatters.py in __call__(self, obj, include, exclude)
    968 
    969             if method is not None:
--> 970                 return method(include=include, exclude=exclude)
    971             return None
    972         else:

/opt/conda/lib/python3.6/site-packages/panel/viewable.py in _repr_mimebundle_(self, include, exclude)
    292         comm = state._comm_manager.get_server_comm()
    293         doc = _Document()
--> 294         model = self._render_model(doc, comm)
    295         if config.embed:
    296             return render_model(model)

/opt/conda/lib/python3.6/site-packages/panel/viewable.py in _render_model(self, doc, comm)
    261         if comm is None:
    262             comm = state._comm_manager.get_server_comm()
--> 263         model = self.get_root(doc, comm)
    264 
    265         if config.embed:

/opt/conda/lib/python3.6/site-packages/panel/viewable.py in get_root(self, doc, comm)
    416         """
    417         doc = doc or _curdoc()
--> 418         root = self._get_model(doc, comm=comm)
    419         self._preprocess(root)
    420         ref = root.ref['id']

/opt/conda/lib/python3.6/site-packages/panel/layout.py in _get_model(self, doc, root, parent, comm)
    113         if root is None:
    114             root = model
--> 115         objects = self._get_objects(model, [], doc, root, comm)
    116         props = dict(self._init_properties(), objects=objects)
    117         model.update(**self._process_param_change(props))

/opt/conda/lib/python3.6/site-packages/panel/layout.py in _get_objects(self, model, old_objects, doc, root, comm)
    105                 child, _ = pane._models[root.ref['id']]
    106             else:
--> 107                 child = pane._get_model(doc, root, model, comm)
    108             new_models.append(child)
    109         return new_models

/opt/conda/lib/python3.6/site-packages/panel/param.py in _get_model(self, doc, root, parent, comm)
    614         if ref in self._models:
    615             self._cleanup(root)
--> 616         model = self._inner_layout._get_model(doc, root, parent, comm)
    617         self._models[ref] = (model, parent)
    618         return model

/opt/conda/lib/python3.6/site-packages/panel/layout.py in _get_model(self, doc, root, parent, comm)
    113         if root is None:
    114             root = model
--> 115         objects = self._get_objects(model, [], doc, root, comm)
    116         props = dict(self._init_properties(), objects=objects)
    117         model.update(**self._process_param_change(props))

/opt/conda/lib/python3.6/site-packages/panel/layout.py in _get_objects(self, model, old_objects, doc, root, comm)
    105                 child, _ = pane._models[root.ref['id']]
    106             else:
--> 107                 child = pane._get_model(doc, root, model, comm)
    108             new_models.append(child)
    109         return new_models

/opt/conda/lib/python3.6/site-packages/panel/pane/vega.py in _get_model(self, doc, root, parent, comm)
    104         else:
    105             json = self._to_json(self.object)
--> 106             self._get_sources(json, sources)
    107         props = self._process_param_change(self._init_properties())
    108         model = VegaPlot(data=json, data_sources=sources, **props)

/opt/conda/lib/python3.6/site-packages/panel/pane/vega.py in _get_sources(self, json, sources)
     76                 import altair as alt
     77                 if (not isinstance(self.object.data, alt.Data) and
---> 78                     columns == set(self.object.data)):
     79                     data = ColumnDataSource.from_df(self.object.data)
     80                 else:

/opt/conda/lib/python3.6/site-packages/altair/utils/schemapi.py in __getitem__(self, item)
    233 
    234     def __getitem__(self, item):
--> 235         return self._kwds[item]
    236 
    237     def __setitem__(self, item, val):

KeyError: 0

Row
    [0] Column
        [0] Select(name='Area type:', options=['Country', 'Sub-Region', ...], value='Country')
    [1] ParamFunction(function)

plot_map() function is working correctly standalone and with ipywidgets interact() function, but here I have this error.
Corresponding to this answer (https://stackoverflow.com/questions/57713504/altair-plot-not-showing-when-using-panel), we need to use default data transformer.
Workaround from #422 is also not working in this case.

@labdmitriy labdmitriy added the TRIAGE Default label for untriaged issues label Nov 13, 2019
@philippjfr
Copy link
Member

philippjfr commented Nov 13, 2019

Thanks for the bug report. Could you update your example to ensure it is fully reproducible? I can guess the imports but don't know where to get data from.

@philippjfr philippjfr added type: bug Something isn't correct or isn't working and removed TRIAGE Default label for untriaged issues labels Nov 13, 2019
@labdmitriy
Copy link
Author

Sure,
merged_stats_df.zip

Full code is the following:

import pandas as pd

import altair as alt
from altair import datum
from vega_datasets import data

import panel as pn
pn.extension('vega')

merged_stats_df = pd.read_csv('merged_stats_df.csv')

alt.renderers.enable('default')
alt.data_transformers.enable('default', max_rows=None)

areas = ['Country', 'Sub-Region', 'Region']
area = pn.widgets.Select(name='Area type:', options=areas)

@pn.depends(area.param.value)
def plot_map(area):
    counter_name = area.lower() + '_count'
    countries = alt.topo_feature(data.world_110m.url, 'countries')
    
    country_map = alt.Chart(countries).mark_geoshape(
    ).encode(
        color=f'{counter_name}:Q',
        tooltip=[
            alt.Tooltip('region:N', title='Region'),
            alt.Tooltip('sub-region:N', title='Sub-Region'),
            alt.Tooltip('answer:N', title='Country'),
            alt.Tooltip(f'{counter_name}:Q', title=f'Questions Count by {area}')
        ]
    ).transform_lookup(
        lookup='id',
        from_=alt.LookupData(merged_stats_df, 'id', merged_stats_df.columns.tolist())
    ).project(
        type='mercator'
    ).properties(
        width=600,
        height=400
    )

    borders = alt.Chart(countries).mark_geoshape(
        fill='white',
        stroke='grey',
        strokeWidth=1
    ).transform_filter(
        datum.id!=10
    ).properties(
        width=600,
        height=400
    )
   
    return (borders + country_map)

pn.Row(
    pn.Column(area),
    plot_map
).servable()

You can try to call for example plot_map('Country') to see that the function itself is working correctly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: bug Something isn't correct or isn't working
Projects
None yet
Development

No branches or pull requests

2 participants