使用 Datashader 从 NumPy 数组绘制数据的最佳方法是什么?
What is the best method for using Datashader to plot data from a NumPy array?
在 Datashader example notebook demonstrating lines 之后,输入是 Pandas DataFrame(尽管 Dask DataFrame 似乎也可以)。我的数据在 NumPy 数组中。我可以使用 Datashader 绘制 NumPy 数组中的线条,而无需先将它们放入 DataFrame 中吗?
line glyph 的文档似乎表明这是可能的,但我没有找到示例。我链接到的示例笔记本使用了我在文档中找不到的 Canvas.line
。
我没有找到在 NumPy 数组中绘制数据而不先将其放入 DataFrame 的方法。如何做到这一点并不是特别直观,Datashader 似乎要求列标签为 non-numeric 字符串,因此可以使用 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
列(最初不直观)。
这是使用散景添加轴的结果示例。
OrderedDict
和 xarray.concat
方法在应用于许多数据曲线时非常慢。以下示例演示了一种更快的方法。有关时间安排和进一步讨论,请参阅 this GitHub issue。
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
在 Datashader example notebook demonstrating lines 之后,输入是 Pandas DataFrame(尽管 Dask DataFrame 似乎也可以)。我的数据在 NumPy 数组中。我可以使用 Datashader 绘制 NumPy 数组中的线条,而无需先将它们放入 DataFrame 中吗?
line glyph 的文档似乎表明这是可能的,但我没有找到示例。我链接到的示例笔记本使用了我在文档中找不到的 Canvas.line
。
我没有找到在 NumPy 数组中绘制数据而不先将其放入 DataFrame 的方法。如何做到这一点并不是特别直观,Datashader 似乎要求列标签为 non-numeric 字符串,因此可以使用 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
列(最初不直观)。
这是使用散景添加轴的结果示例。
OrderedDict
和 xarray.concat
方法在应用于许多数据曲线时非常慢。以下示例演示了一种更快的方法。有关时间安排和进一步讨论,请参阅 this GitHub issue。
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