使用Datashader从NumPy数组绘制数据的最佳方法是什么?

9
在跟随 Datashader 示例 展示线条的笔记本电脑 时,输入是一个 Pandas DataFrame(尽管 Dask DataFrame 似乎也可以)。我的数据在一个 NumPy 数组中。我能否使用 Datashader 绘制来自 NumPy 数组的线条,而无需先将它们放入 DataFrame 中? 线条符号 的文档似乎表明这是可能的,但我没有找到示例。我链接的示例笔记本使用 Canvas.line,但我在文档中没有找到它。
2个回答

7
我没有找到在不先将NumPy数组放入DataFrame的情况下绘制数据的方法。如何做这件事并不是特别直观,似乎Datashader要求列标签为非数字字符串,以便可以使用df.col_label语法调用它们(而不是df[col_label]语法,也许有一个很好的理由)。根据当前系统,我必须执行以下操作才能将NumPy数组转换为具有Datashader可接受列标签的DataFrame。
df = pd.DataFrame(data=data.T)
data_cols = ['c{}'.format(c) for c in df.columns]
df.columns = data_cols
df['x'] = x_values

y_range = data.min(), data.max()
x_range = x_values[0], x_values[-1]

canvas = datashader.Canvas(x_range=x_range, y_range=y_range, 
                           plot_height=300, plot_width=900)
aggs = collections.OrderedDict((c, canvas.line(df, 'q', c)) for c in data_cols)

merged = xarray.concat(saxs_aggs.values(), dim=pd.Index(cols, name='cols'))
saxs_img = datashader.transfer_functions.shade(merged.sum(dim='cols'), 
                                               how='eq_hist')

请注意,使用data_cols变量是非常重要的,而不仅仅是使用df.columns,因为它必须排除x列(这一点最初并不直观)。
以下是使用bokeh添加轴线的结果示例。 enter image description here

error, status code: 429, message: Rate limit reached for default-gpt-3.5-turbo in organization org-HHYtgFtDw4VsdlhuRK1UCbv4 on requests per min. Limit: 3 / min. Please try again in 20s. Contact us through our help center at help.openai.com if you continue to have issues. Please add a payment method to your account to increase your rate limit. Visit https://platform.openai.com/account/billing to add a payment method. - James A. Bednar
1
@JamesA.Bednar 对于如何做的问题,我更喜欢在Stack Overflow上提问,部分原因是为了帮助他人,另一方面也是出于自私的原因,可以轻松地找到参考资料。您是否希望将问题归档为Github问题?我认为这通常是不鼓励的。我将提交一个与列标签相关的问题和接受numpy数组的想法。 - Steven C. Howell
1
SO非常适合用于使用问题,如果您认为必须已经有一种方法来完成某件事情,而您只需要有人帮助您找出是什么。但是SO不适合DataShader开发人员跟踪功能请求和错误报告,因为这两者都极不可能在某些随机的SO帖子中得到解决。当然,通常很难判断您处于哪种情况,即您自己的理解或软件本身的问题。在这种情况下,需要改进的是软件,而不是您,请提交Github问题。 - James A. Bednar

2

OrderedDictxarray.concat方法在应用于多个数据曲线时非常缓慢。以下示例演示了一种更快的方法。有关计时和进一步讨论,请参见此 GitHub 问题

import pandas as pd
import numpy as np
import datashader
import bokeh.plotting
import collections
import xarray
import time
from bokeh.palettes import Colorblind7 as palette

bokeh.plotting.output_notebook()

# create some data worth plotting
nx = 50
x = np.linspace(0, np.pi * 2, nx)
y = np.sin(x)
n = 10000
data = np.empty([n+1, len(y)])
data[0] = x
prng = np.random.RandomState(123)

# scale the data using a random normal distribution
offset = prng.normal(0, 0.1, n).reshape(n, -1)
data[1:] = y
data[1:] += offset

# make some data noisy
n_noisy = prng.randint(0, n,5)
for i in n_noisy:
    data[i+1] += prng.normal(0, 0.5, nx)

dfs = []
split = pd.DataFrame({'x': [np.nan]})
for i in range(len(data)-1):
    x = data[0]
    y = data[i+1]
    df = pd.DataFrame({'x': x, 'y': y})
    dfs.append(df)
    dfs.append(split)

df = pd.concat(dfs, ignore_index=True)   

canvas = datashader.Canvas(x_range=x_range, y_range=y_range, 
                           plot_height=300, plot_width=300)
agg = canvas.line(df, 'x', 'y', datashader.count())
img = datashader.transfer_functions.shade(agg, how='eq_hist')
img

enter image description here


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接