我正在尝试在 Snowflake 上的 Streamlit 应用程序中制作分区统计图。
除了雪花之外,我可以使用以下代码来渲染一张地图,其中阿拉巴马州只有一个县采用颜色编码。
import streamlit as st
import altair as alt
import pandas as pd
us_counties = alt.topo_feature(data.us_10m.url, "counties")
dist_background = alt.Chart(us_counties).mark_geoshape(fill="lightgray", stroke="white").project("albersUsa")
df = {"FIPS_CD": 1001,
"FIPS_COLOR": 1}
df = pd.DataFrame(df, index=[0])
dist_foreground = (
alt.Chart(us_counties)
.mark_geoshape()
.transform_lookup(lookup="id", from_=alt.LookupData(df, "FIPS_CD", ["FIPS_COLOR"]))
.encode(color=alt.Color("FIPS_COLOR:Q"))
.project(type="albersUsa")
)
dist_chart = alt.layer(dist_background, dist_foreground).properties(width=800, height=800)
st.altair_chart(dist_chart, use_container_width=True)
但是,如果我尝试在 Snowflake 的 Streamlit 应用程序中运行相同的代码,它根本不会呈现。我得到一个空白,仅显示图例,但图例在 Snowflake 中显示“NaN”,当我在 Snowflake 环境之外运行代码时,图例显示 1。我可以看到通过单击绘图旁边的省略号并转到 vega 编辑器来加载数据。当我这样做时,我看到整个国家都被绘制出来,但颜色编码不存在。
Snowflake 到底在幕后做了什么,才把事情搞砸了? 在 Snowflake 上,我使用的软件包选项是:
问题在于 Altair 尝试从前端的外部 CDN 加载 topojson 文件,该文件被 Snowflake 设置的内容安全策略阻止(出于安全原因,该策略阻止 Snowflake 应用程序中的 Streamlit 访问任意外部域)。
如果您在运行应用程序时打开浏览器开发者控制台,您应该会看到与此类似的日志,其中指出了问题:
Refused to connect to 'https://cdn.jsdelivr.net/npm/[email protected]/data/us-10m.json' because it violates the document's Content Security Policy.
今天可用的解决方法是使用应用程序阶段的 topojson 文件的本地副本 - 我不是 Altair topo 功能的专家,但我知道 plotly.express.choropleth_mapbox 支持此功能。
顺便说一句,要重现示例代码,您需要添加
from vega_datasets import data
。