mirror of
https://github.com/aykhans/AzSuicideDataVisualization.git
synced 2025-04-23 02:40:43 +00:00
200 lines
6.1 KiB
Python
200 lines
6.1 KiB
Python
# Copyright 2018-2022 Streamlit Inc.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
|
|
"""A Python wrapper around Vega-Lite."""
|
|
|
|
import json
|
|
from typing import cast
|
|
|
|
import streamlit
|
|
import streamlit.elements.legacy_data_frame as data_frame
|
|
import streamlit.elements.lib.dicttools as dicttools
|
|
from streamlit.logger import get_logger
|
|
from streamlit.proto.VegaLiteChart_pb2 import VegaLiteChart as VegaLiteChartProto
|
|
|
|
LOGGER = get_logger(__name__)
|
|
|
|
|
|
class LegacyVegaLiteMixin:
|
|
def _legacy_vega_lite_chart(
|
|
self,
|
|
data=None,
|
|
spec=None,
|
|
use_container_width=False,
|
|
**kwargs,
|
|
):
|
|
"""Display a chart using the Vega-Lite library.
|
|
|
|
Parameters
|
|
----------
|
|
data : pandas.DataFrame, pandas.Styler, numpy.ndarray, Iterable, dict,
|
|
or None
|
|
Either the data to be plotted or a Vega-Lite spec containing the
|
|
data (which more closely follows the Vega-Lite API).
|
|
|
|
spec : dict or None
|
|
The Vega-Lite spec for the chart. If the spec was already passed in
|
|
the previous argument, this must be set to None. See
|
|
https://vega.github.io/vega-lite/docs/ for more info.
|
|
|
|
use_container_width : bool
|
|
If True, set the chart width to the column width. This takes
|
|
precedence over Vega-Lite's native `width` value.
|
|
|
|
**kwargs : any
|
|
Same as spec, but as keywords.
|
|
|
|
Example
|
|
-------
|
|
|
|
>>> import pandas as pd
|
|
>>> import numpy as np
|
|
>>>
|
|
>>> df = pd.DataFrame(
|
|
... np.random.randn(200, 3),
|
|
... columns=['a', 'b', 'c'])
|
|
>>>
|
|
>>> st._legacy_vega_lite_chart(df, {
|
|
... 'mark': {'type': 'circle', 'tooltip': True},
|
|
... 'encoding': {
|
|
... 'x': {'field': 'a', 'type': 'quantitative'},
|
|
... 'y': {'field': 'b', 'type': 'quantitative'},
|
|
... 'size': {'field': 'c', 'type': 'quantitative'},
|
|
... 'color': {'field': 'c', 'type': 'quantitative'},
|
|
... },
|
|
... })
|
|
|
|
.. output::
|
|
https://static.streamlit.io/0.25.0-2JkNY/index.html?id=8jmmXR8iKoZGV4kXaKGYV5
|
|
height: 200px
|
|
|
|
Examples of Vega-Lite usage without Streamlit can be found at
|
|
https://vega.github.io/vega-lite/examples/. Most of those can be easily
|
|
translated to the syntax shown above.
|
|
|
|
"""
|
|
vega_lite_chart_proto = VegaLiteChartProto()
|
|
marshall(
|
|
vega_lite_chart_proto,
|
|
data,
|
|
spec,
|
|
use_container_width=use_container_width,
|
|
**kwargs,
|
|
)
|
|
return self.dg._enqueue("vega_lite_chart", vega_lite_chart_proto)
|
|
|
|
@property
|
|
def dg(self) -> "streamlit.delta_generator.DeltaGenerator":
|
|
"""Get our DeltaGenerator."""
|
|
return cast("streamlit.delta_generator.DeltaGenerator", self)
|
|
|
|
|
|
def marshall(proto, data=None, spec=None, use_container_width=False, **kwargs):
|
|
"""Construct a Vega-Lite chart object.
|
|
|
|
See DeltaGenerator._legacy_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.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 spec["data"]
|
|
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.marshall_data_frame(data, proto.data)
|
|
|
|
|
|
# See https://vega.github.io/vega-lite/docs/encoding.html
|
|
_CHANNELS = set(
|
|
[
|
|
"x",
|
|
"y",
|
|
"x2",
|
|
"y2",
|
|
"xError",
|
|
"yError2",
|
|
"xError",
|
|
"yError2",
|
|
"longitude",
|
|
"latitude",
|
|
"color",
|
|
"opacity",
|
|
"fillOpacity",
|
|
"strokeOpacity",
|
|
"strokeWidth",
|
|
"size",
|
|
"shape",
|
|
"text",
|
|
"tooltip",
|
|
"href",
|
|
"key",
|
|
"order",
|
|
"detail",
|
|
"facet",
|
|
"row",
|
|
"column",
|
|
]
|
|
)
|