在全息视图中,如何对叠加层的分类轴进行排序?
In holoviews, how do I sort categorical axes of an Overlay?
我有一个 pandas 数据框,其中包含 3 个分类列(A、B、C)和 1 个数字列 (N)。我绘制了一个 x 轴 A、y 轴 N 并按 B 分层的散点图(为了便于参考,我们只制作此二进制文件)。因此,每个 A-C 组合都有一个点,由 B(2 种颜色)着色。这会产生一个 NdLayout 对象。
现在我正在尝试使 x 轴的顺序正确,其中值按该类别的值的绝对总和排序(不考虑层,即 B)。
如果我简单地根据组总和对数据框中 A 的条目进行排序,它适用于大多数情况。但是,在一种情况下,B 的特定层没有 A-C 条目,即缺少数据。例如,如果 B=1,则 A 的值对于该层不存在,但对于 B=0 则存在。所以当绘制这个时,值被添加到错误的地方,因为我正在使用 NdLayout。
是否有 post 绘图过程来更改维度中的因子排序?
import holoviews as hv
hv.extension("matplotlib")
import colorcet as cc
ds = hv.Dataset(data,kdims=["A"],vdims=["N","B"])
scatter = ds.to(hv.Scatter,"A","N","B").overlay().opts(opts.Scatter(color=hv.Cycle([cc.isolum[0]] + [cc.isolum[-1]]),xrotation=90))
示例:
A = ['Sample_{}'.format(ii) for ii in range(20)]
C = ['Category_{}'.format(ii) for ii in range(10)]
b_data = np.asarray([np.random.normal(0,xx+1,size=10) for xx in range(20)])
B_1 = pd.DataFrame(b_data,index=A,columns=C)
B_1 = B_1.rename_axis('A').reset_index().melt(id_vars='A',value_name='N',var_name='C')
B_1['B'] = 1
#create data set with one of the Sample_ entries removed.
b_data = np.asarray([np.random.normal(0,xx+1,size=10) for xx in range(19)])
B_0 = pd.DataFrame(b_data,index=A[:-1],columns=C)
B_0 = B_0.rename_axis('A').reset_index().melt(id_vars='A',value_name='N',var_name='C')
B_0['B'] = 0
myData = pd.concat([B_1,B_0])
featureOrder = myData.groupby('A')['N'].apply(lambda x: x.abs().sum()).sort_values(ascending=False).index
myData['A'] = pd.Categorical(myData.A, categories=featureOrder,ordered=True)
myData =myData.sort_values(by='A')
#generate plot using hvplot
myData.hvplot.scatter(x='A',y='N',by='B').opts(padding=0.1,xrotation=90)
#the following gives the same output, but doesn't use hvplot
ds = hv.Dataset(myData,kdims=["A"],vdims=["N","B"])
scatter = ds.to(hv.Scatter,"A","N","B").overlay().opts(opts.Scatter(color=hv.Cycle([cc.isolum[0]] + [cc.isolum[-1]]),xrotation=90))
print(featureOrder)
Index(['Sample_17', 'Sample_18', 'Sample_13', 'Sample_16', 'Sample_11',
'Sample_15', 'Sample_14', 'Sample_10', 'Sample_19', 'Sample_12',
'Sample_9', 'Sample_6', 'Sample_8', 'Sample_7', 'Sample_5', 'Sample_4',
'Sample_3', 'Sample_2', 'Sample_1', 'Sample_0'],
dtype='object', name='A')
从情节Sample_19添加到最后,而它应该是第9。如果我改变 B 的值,那么绘图的顺序是正确的。
根据您上面的示例,如果您将 scatter[1] * scatter[0]
与 scatter[0] * scatter[1]
进行比较,您会发现它是 Overlay 的第一个元素,它定义了分类轴的顺序,其余的是刚刚附加(正如您已经发现的那样)。
目前的一个解决方法是为您希望成为排序一部分的所有缺失数据插入 NaN。
(有关分类轴排序的更通用方法,这是最近几个问题的内容,希望有一天会实现 - 请参阅我的评论中链接的 github 个问题。)
我有一个 pandas 数据框,其中包含 3 个分类列(A、B、C)和 1 个数字列 (N)。我绘制了一个 x 轴 A、y 轴 N 并按 B 分层的散点图(为了便于参考,我们只制作此二进制文件)。因此,每个 A-C 组合都有一个点,由 B(2 种颜色)着色。这会产生一个 NdLayout 对象。
现在我正在尝试使 x 轴的顺序正确,其中值按该类别的值的绝对总和排序(不考虑层,即 B)。
如果我简单地根据组总和对数据框中 A 的条目进行排序,它适用于大多数情况。但是,在一种情况下,B 的特定层没有 A-C 条目,即缺少数据。例如,如果 B=1,则 A 的值对于该层不存在,但对于 B=0 则存在。所以当绘制这个时,值被添加到错误的地方,因为我正在使用 NdLayout。
是否有 post 绘图过程来更改维度中的因子排序?
import holoviews as hv
hv.extension("matplotlib")
import colorcet as cc
ds = hv.Dataset(data,kdims=["A"],vdims=["N","B"])
scatter = ds.to(hv.Scatter,"A","N","B").overlay().opts(opts.Scatter(color=hv.Cycle([cc.isolum[0]] + [cc.isolum[-1]]),xrotation=90))
示例:
A = ['Sample_{}'.format(ii) for ii in range(20)]
C = ['Category_{}'.format(ii) for ii in range(10)]
b_data = np.asarray([np.random.normal(0,xx+1,size=10) for xx in range(20)])
B_1 = pd.DataFrame(b_data,index=A,columns=C)
B_1 = B_1.rename_axis('A').reset_index().melt(id_vars='A',value_name='N',var_name='C')
B_1['B'] = 1
#create data set with one of the Sample_ entries removed.
b_data = np.asarray([np.random.normal(0,xx+1,size=10) for xx in range(19)])
B_0 = pd.DataFrame(b_data,index=A[:-1],columns=C)
B_0 = B_0.rename_axis('A').reset_index().melt(id_vars='A',value_name='N',var_name='C')
B_0['B'] = 0
myData = pd.concat([B_1,B_0])
featureOrder = myData.groupby('A')['N'].apply(lambda x: x.abs().sum()).sort_values(ascending=False).index
myData['A'] = pd.Categorical(myData.A, categories=featureOrder,ordered=True)
myData =myData.sort_values(by='A')
#generate plot using hvplot
myData.hvplot.scatter(x='A',y='N',by='B').opts(padding=0.1,xrotation=90)
#the following gives the same output, but doesn't use hvplot
ds = hv.Dataset(myData,kdims=["A"],vdims=["N","B"])
scatter = ds.to(hv.Scatter,"A","N","B").overlay().opts(opts.Scatter(color=hv.Cycle([cc.isolum[0]] + [cc.isolum[-1]]),xrotation=90))
print(featureOrder)
Index(['Sample_17', 'Sample_18', 'Sample_13', 'Sample_16', 'Sample_11',
'Sample_15', 'Sample_14', 'Sample_10', 'Sample_19', 'Sample_12',
'Sample_9', 'Sample_6', 'Sample_8', 'Sample_7', 'Sample_5', 'Sample_4',
'Sample_3', 'Sample_2', 'Sample_1', 'Sample_0'],
dtype='object', name='A')
从情节Sample_19添加到最后,而它应该是第9。如果我改变 B 的值,那么绘图的顺序是正确的。
根据您上面的示例,如果您将 scatter[1] * scatter[0]
与 scatter[0] * scatter[1]
进行比较,您会发现它是 Overlay 的第一个元素,它定义了分类轴的顺序,其余的是刚刚附加(正如您已经发现的那样)。
目前的一个解决方法是为您希望成为排序一部分的所有缺失数据插入 NaN。
(有关分类轴排序的更通用方法,这是最近几个问题的内容,希望有一天会实现 - 请参阅我的评论中链接的 github 个问题。)