与 Altair 交互绘制时间序列的问题
Problems plotting time-series interactively with Altair
问题描述
我的目标很基本:在交互式图中绘制时间序列。经过一些研究,我决定尝试 Altair。
已经有 QGIS plugins 用于时间序列可视化,但据我所知,none 用于在矢量级别绘制时间序列,交互式单击地图并选择多边形。所以这就是为什么我决定使用 Altair 寻求一个自制的解决方案,也许将它与 Folium 结合起来以在以后添加功能。
我是 Altair 库(以及 Vega 和 Vega-lite)的新手,在数据科学和数据可视化方面也是新手...所以提前为我的无知道歉!
已经有关于如何使用 Altair 绘制时间序列的很好解释的教程(例如 here,或在官方网站上)。但是,据我所知,我的研究案例有一些特殊性尚未完全解决。
数据是使用 Python API for Google Earth Engine 生成的,并使用 Python 和 pandas/geopandas 库进行了预处理:
在Google Earth Engine中,植被指数(当前情况下的NDVI)是在像素级计算特定区域的兴趣(投资回报率)。然后函数 image.reduceRegions() 映射到 ImageCollection 以计算 FeatureCollection 元素的每个多边形中 ndvi 的平均值,它表示农业包裹。导出生成的 矢量文件 。
在Jupyter-lab环境下,数据被加载到geopandas GeoDataFrame对象中并进行预处理,转置DataFrame 并创建一个 datetime 列等,以便使用 Altair 为时间序列表示提供良好的数据形状。
预处理后的数据概览:
我的“最终”目标是在同一张图中显示一个交互式线图,其中一组线代表一个农业地块,地块按不同颜色的作物类型分类,例如绿色的玉米,黄色的小麦,棕色的同类树...(包含每个地块作物类型的信息可以添加到 DataFrame 与另一个 DataFrame).
我想的东西看起来或多或少类似于以下示例,传说中的年份是按作物类型着色的地块:
但到目前为止,我还没有设法让我的数据看起来像这样......根本没有。
如您所见,数据中有许多空值(这是由于云掩蔽函数的应用以及多个 Sentinel-2 轨道与 ROI 相交所致)。我只想省略 earch column/parcel 的非空值,但我不知道此数据配置是否会带来问题(对此有何建议?)。
到目前为止我得到了:
- 生成前面的图形,对于单个包裹,已经花费了大约 23 秒。哪些方面可能 shoud/cloud 需要改进(如何?)
- 更重要的是,代表 item/polygon/parcel 值 (NDVI) 的预期线甚至没有显示在图中 (请注意,我选择了一个包含相当少的非空值)。
确实我做错了很多事。如果能得到一些建议来解决(其中一些)问题,那就太好了。
重现问题的数据和代码示例
Here 是 JSON 格式的数据文本示例,用于重现问题的代码如下:
import pandas as pd
import geopandas as gpd
import altair as alt
df= pd.read_json(r"path\to\json\file.json")
df['date']= pd.to_datetime(df['date'])
print(gdf.dtypes)
df
输出:
lines=alt.Chart(df).mark_line().encode(
x='date:O',
y='17811:Q',
color=alt.Color(
'17811:Q', scale=alt.Scale(scheme='redyellowgreen', domain=(-1, 1)))
)
lines.properties(width=700, height=600).interactive()
输出:
在此先感谢您的帮助!
如果我理解正确,主要是你的数据框格式需要更改 from wide to long,你可以通过 pandas 中的 .melt
或 [=14] =] 在牵牛星。对于熔化,熔化列的默认名称为 'variable'
(前一列名称)和 'value'
(每列的值):
alt.Chart(df.melt(id_vars='date'), width=500).mark_line().encode(
x='date:T',
y='value',
color=alt.Color('variable')
)
差距来自NaN;如果您希望 Altair 插入缺失值,您可以删除 NaN:
alt.Chart(df.melt(id_vars='date').dropna(), width=500).mark_line().encode(
x='date:T',
y='value',
color=alt.Color('variable')
)
如果你想在 Altair 中完成所有操作,以下等效于上面最后一个 pandas 示例(转换使用 'key'
而不是 'variable'
作为名称前专栏)。我还使用和序号而不是标称类型进行颜色编码,以展示如何使颜色与您的示例更相似。:
alt.Chart(df, width=500).mark_line().encode(
x='date:T',
y='value:Q',
color=alt.Color('key:O')
).transform_fold(
df.drop(columns='date').columns.tolist()
).transform_filter(
'isValid(datum.value)'
)
问题描述
我的目标很基本:在交互式图中绘制时间序列。经过一些研究,我决定尝试 Altair。 已经有 QGIS plugins 用于时间序列可视化,但据我所知,none 用于在矢量级别绘制时间序列,交互式单击地图并选择多边形。所以这就是为什么我决定使用 Altair 寻求一个自制的解决方案,也许将它与 Folium 结合起来以在以后添加功能。
我是 Altair 库(以及 Vega 和 Vega-lite)的新手,在数据科学和数据可视化方面也是新手...所以提前为我的无知道歉!
已经有关于如何使用 Altair 绘制时间序列的很好解释的教程(例如 here,或在官方网站上)。但是,据我所知,我的研究案例有一些特殊性尚未完全解决。
数据是使用 Python API for Google Earth Engine 生成的,并使用 Python 和 pandas/geopandas 库进行了预处理:
在Google Earth Engine中,植被指数(当前情况下的NDVI)是在像素级计算特定区域的兴趣(投资回报率)。然后函数 image.reduceRegions() 映射到 ImageCollection 以计算 FeatureCollection 元素的每个多边形中 ndvi 的平均值,它表示农业包裹。导出生成的 矢量文件 。
在Jupyter-lab环境下,数据被加载到geopandas GeoDataFrame对象中并进行预处理,转置DataFrame 并创建一个 datetime 列等,以便使用 Altair 为时间序列表示提供良好的数据形状。
预处理后的数据概览:
我的“最终”目标是在同一张图中显示一个交互式线图,其中一组线代表一个农业地块,地块按不同颜色的作物类型分类,例如绿色的玉米,黄色的小麦,棕色的同类树...(包含每个地块作物类型的信息可以添加到 DataFrame 与另一个 DataFrame).
我想的东西看起来或多或少类似于以下示例,传说中的年份是按作物类型着色的地块:
但到目前为止,我还没有设法让我的数据看起来像这样......根本没有。
如您所见,数据中有许多空值(这是由于云掩蔽函数的应用以及多个 Sentinel-2 轨道与 ROI 相交所致)。我只想省略 earch column/parcel 的非空值,但我不知道此数据配置是否会带来问题(对此有何建议?)。
到目前为止我得到了:
- 生成前面的图形,对于单个包裹,已经花费了大约 23 秒。哪些方面可能 shoud/cloud 需要改进(如何?)
- 更重要的是,代表 item/polygon/parcel 值 (NDVI) 的预期线甚至没有显示在图中 (请注意,我选择了一个包含相当少的非空值)。
确实我做错了很多事。如果能得到一些建议来解决(其中一些)问题,那就太好了。
重现问题的数据和代码示例
Here 是 JSON 格式的数据文本示例,用于重现问题的代码如下:
import pandas as pd
import geopandas as gpd
import altair as alt
df= pd.read_json(r"path\to\json\file.json")
df['date']= pd.to_datetime(df['date'])
print(gdf.dtypes)
df
输出:
lines=alt.Chart(df).mark_line().encode(
x='date:O',
y='17811:Q',
color=alt.Color(
'17811:Q', scale=alt.Scale(scheme='redyellowgreen', domain=(-1, 1)))
)
lines.properties(width=700, height=600).interactive()
输出:
在此先感谢您的帮助!
如果我理解正确,主要是你的数据框格式需要更改 from wide to long,你可以通过 pandas 中的 .melt
或 [=14] =] 在牵牛星。对于熔化,熔化列的默认名称为 'variable'
(前一列名称)和 'value'
(每列的值):
alt.Chart(df.melt(id_vars='date'), width=500).mark_line().encode(
x='date:T',
y='value',
color=alt.Color('variable')
)
差距来自NaN;如果您希望 Altair 插入缺失值,您可以删除 NaN:
alt.Chart(df.melt(id_vars='date').dropna(), width=500).mark_line().encode(
x='date:T',
y='value',
color=alt.Color('variable')
)
如果你想在 Altair 中完成所有操作,以下等效于上面最后一个 pandas 示例(转换使用 'key'
而不是 'variable'
作为名称前专栏)。我还使用和序号而不是标称类型进行颜色编码,以展示如何使颜色与您的示例更相似。:
alt.Chart(df, width=500).mark_line().encode(
x='date:T',
y='value:Q',
color=alt.Color('key:O')
).transform_fold(
df.drop(columns='date').columns.tolist()
).transform_filter(
'isValid(datum.value)'
)