def marshall(proto, spec=None, **kwargs): """Marshall a proto with DeckGL chart info. See DeltaGenerator.deck_gl_chart for docs. """ if "data" in kwargs: # TODO: Remove this check after 2019-11-28. raise Exception( "The `data` parameter is deprecated. Use `st.map` or" "specify a spec dict in `st.deck_gl_chart`." ) data = [] if spec is None: spec = dict() # Merge spec with unflattened kwargs, where kwargs take precedence. # This only works for string keys, but kwarg keys are strings anyways. spec = dict(spec, **dicttools.unflatten(kwargs)) if "layers" not in spec: spec["layers"] = [] # Syntax sugar: if no layers defined and data is passed at the top # level, create a scatterplot layer with the top-level data by default. if data is not None: spec["layers"].append({"data": data, "type": "ScatterplotLayer"}) for layer in spec["layers"]: # Don't add layers that have no data. if "data" not in layer: continue # Remove DataFrame because it's not JSON-serializable data = layer.pop("data") layer_proto = proto.layers.add() fixed_layer = case_converters.convert_dict_keys( case_converters.to_lower_camel_case, layer ) layer_proto.spec = json.dumps(fixed_layer) # TODO: If several layers use the same data frame, the data gets resent # for each layer. Need to improve this. data_frame_proto.marshall_data_frame(data, layer_proto.data) del spec["layers"] # Dump JSON after removing DataFrames (see loop above), because DataFrames # are not JSON-serializable. proto.spec = json.dumps(spec)
def marshall(proto, data=None, spec=None, **kwargs): """Marshall a proto with DeckGL chart info. See DeltaGenerator.deck_gl_chart for docs. """ if data is None: data = [] if spec is None: spec = dict() # Merge spec with unflattened kwargs, where kwargs take precedence. # This only works for string keys, but kwarg keys are strings anyways. spec = dict(spec, **dicttools.unflatten(kwargs)) if 'layers' not in spec: spec['layers'] = [] # Syntax sugar: if no layers defined and data is passed at the top # level, create a scatterplot layer with the top-level data by default. if data is not None: spec['layers'].append({ 'data': data, 'type': 'ScatterplotLayer', }) for layer in spec['layers']: # Don't add layers that have no data. if 'data' not in layer: continue # Remove DataFrame because it's not JSON-serializable data = layer.pop('data') layer_proto = proto.layers.add() fixed_layer = case_converters.convert_dict_keys( case_converters.to_lower_camel_case, layer) layer_proto.spec = json.dumps(fixed_layer) # TODO: If several layers use the same data frame, the data gets resent # for each layer. Need to improve this. data_frame_proto.marshall_data_frame(data, layer_proto.data) del spec['layers'] # Dump JSON after removing DataFrames (see loop above), because DataFrames # are not JSON-serializable. proto.spec = json.dumps(spec)
def marshall(proto, data=None, spec=None, use_container_width=False, **kwargs): """Construct a Vega-Lite chart object. See DeltaGenerator.vega_lite_chart for docs. """ # Support passing data inside spec['datasets'] and spec['data']. # (The data gets pulled out of the spec dict later on.) if isinstance(data, dict) and spec is None: spec = data data = None # Support passing no spec arg, but filling it with kwargs. # Example: # marshall(proto, baz='boz') if spec is None: spec = dict() else: # Clone the spec dict, since we may be mutating it. spec = dict(spec) # Support passing in kwargs. Example: # marshall(proto, {foo: 'bar'}, baz='boz') if len(kwargs): # Merge spec with unflattened kwargs, where kwargs take precedence. # This only works for string keys, but kwarg keys are strings anyways. spec = dict(spec, **dicttools.unflatten(kwargs, _CHANNELS)) if len(spec) == 0: raise ValueError("Vega-Lite charts require a non-empty spec dict.") if "autosize" not in spec: spec["autosize"] = {"type": "fit", "contains": "padding"} # Pull data out of spec dict when it's in a 'dataset' key: # marshall(proto, {datasets: {foo: df1, bar: df2}, ...}) if "datasets" in spec: for k, v in spec["datasets"].items(): dataset = proto.datasets.add() dataset.name = str(k) dataset.has_name = True data_frame_proto.marshall_data_frame(v, dataset.data) del spec["datasets"] # Pull data out of spec dict when it's in a top-level 'data' key: # marshall(proto, {data: df}) # marshall(proto, {data: {values: df, ...}}) # marshall(proto, {data: {url: 'url'}}) # marshall(proto, {data: {name: 'foo'}}) if "data" in spec: data_spec = spec["data"] if isinstance(data_spec, dict): if "values" in data_spec: data = data_spec["values"] del data_spec["values"] else: data = data_spec del spec["data"] proto.spec = json.dumps(spec) proto.use_container_width = use_container_width if data is not None: data_frame_proto.marshall_data_frame(data, proto.data)
def marshall(proto, data=None, spec=None, width=0, **kwargs): """Construct a Vega-Lite chart object. See DeltaGenerator.vega_lite_chart for docs. """ # Support passing data inside spec['datasets'] and spec['data']. # (The data gets pulled out of the spec dict later on.) if type(data) in dict_types and spec is None: spec = data data = None # Support passing no spec arg, but filling it with kwargs. # Example: # marshall(proto, baz='boz') if spec is None: spec = dict() else: # Clone the spec dict, since we may be mutating it. spec = dict(spec) # Support passing in kwargs. Example: # marshall(proto, {foo: 'bar'}, baz='boz') if len(kwargs): # Merge spec with unflattened kwargs, where kwargs take precedence. # This only works for string keys, but kwarg keys are strings anyways. spec = dict(spec, **dicttools.unflatten(kwargs, _CHANNELS)) if len(spec) == 0: raise ValueError('Vega-Lite charts require a non-empty spec dict.') # TODO: Improve autosizing code. It doesn't work with some kinds of charts, # like composed charts, for example. if width >= 0 and 'width' not in spec: spec['width'] = width if 'autosize' not in spec: spec['autosize'] = {'type': 'fit', 'contains': 'padding'} # Pull data out of spec dict when it's in a 'dataset' key: # marshall(proto, {datasets: {foo: df1, bar: df2}, ...}) if 'datasets' in spec: for k, v in spec['datasets'].items(): dataset = proto.datasets.add() dataset.name = str(k) dataset.has_name = True data_frame_proto.marshall_data_frame(v, dataset.data) del spec['datasets'] # Pull data out of spec dict when it's in a top-level 'data' key: # marshall(proto, {data: df}) # marshall(proto, {data: {values: df, ...}}) # marshall(proto, {data: {url: 'url'}}) # marshall(proto, {data: {name: 'foo'}}) if 'data' in spec: data_spec = spec['data'] if type(data_spec) in dict_types: if 'values' in data_spec: data = data_spec['values'] del data_spec['values'] else: data = data_spec del spec['data'] proto.spec = json.dumps(spec) if data is not None: data_frame_proto.marshall_data_frame(data, proto.data)