如何在大型数据集上创建交互式图形?

2024-04-24 10:50:26 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图在一个大数据集上使用全息视图创建一个交互式图形。下面是名为trackData.cvs的数据文件示例

Event         Time             ID     Venue    
Javeline      11:25:21:012345  JVL    Dome
Shot pot      11:25:22:778929  SPT    Dome
4x4           11:25:21:993831  FOR    Track
4x4           11:25:22:874293  FOR    Track
Shot pot      11:25:21:087822  SPT    Dome
Javeline      11:25:23:878792  JVL    Dome
Long Jump     11:25:21:892902  LJP    Aquatic
Long Jump     11:25:22:799422  LJP    Aquatic

这就是我读取数据并绘制散点图的方式

trackData = pd.read_csv('trackData.csv')
scatter = hv.Scatter(trackData, 'Time', 'ID')
scatter

因为这个数据集非常庞大,所以放大和缩小散点图的速度非常慢,希望加快这个过程。 我研究并发现了在大型数据集上推荐的holoviews decimate,但我不知道如何在上面的代码中使用。 我试过的大多数案例似乎都出错了。另外,是否有办法确保时间列转换为微秒?提前谢谢你的帮助


Tags: 数据idfortimetracklong集上shot
2条回答

decimate()的缺点是它会对数据点进行下采样。
我认为这里需要datashader(),但是datashader不喜欢ID是一个分类变量而不是一个数值

因此,一个解决方案是将分类变量转换为数字代码。

有关hvPlot(我更喜欢)和HoloViews,请参见下面的代码示例:

import io
import pandas as pd
import hvplot.pandas
import holoviews as hv
# dynspread is for making point sizes larger when using datashade
from holoviews.operation.datashader import datashade, dynspread

# sample data
text = """
    Event         Time             ID     Venue    
    Javeline      11:25:21:012345  JVL    Dome
    Shot pot      11:25:22:778929  SPT    Dome
    4x4           11:25:21:993831  FOR    Track
    4x4           11:25:22:874293  FOR    Track
    Shot pot      11:25:21:087822  SPT    Dome
    Javeline      11:25:23:878792  JVL    Dome
    Long Jump     11:25:21:892902  LJP    Aquatic
    Long Jump     11:25:22:799422  LJP    Aquatic
"""

# create dataframe and parse time
df = pd.read_csv(io.StringIO(text), sep='\s{2,}', engine='python')
df['Time'] = pd.to_datetime(df['Time'], format='%H:%M:%S:%f')
df = df.set_index('Time').sort_index()

# get a column that converts categorical id's to numerical id's
df['ID'] = pd.Categorical(df['ID'])
df['ID_code'] = df['ID'].cat.codes

# use this to overwrite numerical yticks with categorical yticks
yticks=[(0, 'FOR'), (1, 'JVL'), (2, 'LJP'), (3, 'SPT')]

# this is the hvplot solution: set datashader=True
df.hvplot.scatter(
    x='Time', 
    y='ID_code', 
    datashade=True,
    dynspread=True,
    padding=0.05, 
).opts(yticks=yticks)

# this is the holoviews solution
scatter = hv.Scatter(df, kdims=['Time'], vdims=['ID_code'])
dynspread(datashade(scatter)).opts(yticks=yticks, padding=0.05)


有关数据隐藏和抽取的更多信息:
http://holoviews.org/user_guide/Large_Data.html

结果图:

using datashader for large data

Datashader确实没有像这里使用的那样处理分类轴,但这与其说是软件的限制,还不如说是我的想象,它应该如何处理它们呢?Datashader散点图(Canvas.points)适用于连续索引2D平面上的大量点。这样的图近似于2D概率分布函数,每像素累积点以显示该区域的密度,并显示像素之间的空间模式

分类轴与连续数值轴的属性不同,因为相邻值之间没有空间关系。特别是在这种情况下,ID字段的顺序没有明显的意义(它似乎是体育赛事类型的字母代码),因此我看不出像Datashader设计的那样,在每个像素上累积ID值有什么意义。即使将ID转换为数字,也会得到随机外观的噪声(如果ID值大于垂直像素),或者一系列斑点线(如果ID值小于像素)

在这里,可能只有几十个左右的唯一ID值,但是很多很多时间测量?在这种情况下,大多数人会对每个ID使用方框、提琴、直方图或脊线图来查看每个ID值的值分布。Datashader points图是一个2D直方图,但是如果一个轴是分类的,那么你实际上是在处理一组1D直方图,而不是一个单一的组合2D直方图,所以如果你想要的是直方图,就使用直方图

如果您确实想尝试将每个ID的所有点绘制为原始点,那么可以使用垂直尖峰事件(如https://examples.pyviz.org/iex_trading/IEX_stocks.html)来完成。您也可以添加一些垂直抖动,然后使用Datashader,但目前还不直接支持这种方法,而且它没有普通Datashader绘图所具有的清晰数学解释(就近似密度函数而言)

stockstaxi tips

相关问题 更多 >