【问题标题】:Marking data labels on outliers in 3D scatter plot在 3D 散点图中标记异常值上的数据标签
【发布时间】:2013-05-01 21:01:12
【问题描述】:

我有一个如下所示的制表符分隔数据集

Labels  t1  t2  t3
gene1   0.000000E+00    0.000000E+00    1.138501E-01
gene2   0.000000E+00    0.000000E+00    9.550272E-02
gene3   0.000000E+00    1.851936E-02    1.019907E-01
gene4   8.212816E-02    0.000000E+00    6.570984E+00
gene5   1.282434E-01    0.000000E+00    6.240799E+00
gene6   2.918929E-01    8.453281E-01    3.387610E+00
gene7   0.000000E+00    1.923038E-01    0.000000E+00
gene8   1.135057E+00    0.000000E+00    2.491100E+00
gene9   7.935625E-01    1.070320E-01    2.439292E+00
gene10  5.046790E+00    0.000000E+00    2.459273E+00
gene11  3.293614E-01    0.000000E+00    2.380152E+00
gene12  0.000000E+00    0.000000E+00    1.474757E-01
gene13  0.000000E+00    0.000000E+00    1.521591E-01
gene14  0.000000E+00    9.968809E-02    8.387166E-01
gene15  0.000000E+00    1.065761E-01    0.000000E+00

我想要的是:得到一个带有异常值标签的 3d 散点图,如下所示:

我做了什么:在R中

我实际上已经像这样单独阅读了每一列:

library("scatterplot3d")
temp<-read.table("tempdata.txt", header=T)
scatterplot3d(temp1$t1, temp1$t2, temp1$t3)

我想要的是:应该至少为前 250 个显示异常值的标签,或者如何在变量中获取前 250 个异常值的标签以供进一步分析。

谁能在R中指导我完成这个。

也欢迎python中的解决方案。

【问题讨论】:

  • 如何对异常值进行分类? zz/xx/yy 值前 250 位?还是距离原点/平均值/某个点的欧几里得距离?
  • 使用sort(temp1$t1, TRUE)[1:250]可以找到向量的最大值
  • 标签呢?虽然我想出了如何获取它,但我需要根据最后一列中的值过滤我的数据,例如,如果我有两倍的基因 13 值,它应该对其进行排序并根据最后一列中的值给出输出.
  • 不太清楚你的意思。是否要 t3 列的异常值及其对应的标签?

标签: r python-2.7 numpy matplotlib scatter-plot


【解决方案1】:

将 250 个标签绘制成一个图不是一个好的选择,因为它会使图无法阅读。如果您想在绘图中标记异常值,这些异常值应远离其余数据点,以便轻松唯一地识别它们。但是,您可以将最大的 250 zz 值及其对应的标签保存在矩阵中以供进一步分析。我会这样做:

# Create some random data
library("scatterplot3d")
temp1 <- as.data.frame(matrix(rnorm(900), ncol=3))
temp1$labels <- c("gen1", "gen2", "gen3")
colnames(temp1) <- c("t1", "t2", "t3", "labels")

# get the outliers
zz.outlier <- sort(temp1$t3, TRUE)[1:5]
ix <- which(temp1$t3 %in% zz.outlier)
outlier.matrix <- temp1[ix, ]

# create the plot and mark the points
sd3 <- scatterplot3d(temp1$t1, temp1$t2, temp1$t3)
sd3$points3d(temp1$t1[ix],temp1$t2[ix],temp1$t2[ix], col="red")
text(sd3$xyz.convert(temp1$t1[ix],temp1$t2[ix],temp1$t2[ix]), 
     labels=temp1$labels[ix])

这里我也用红色标记了点。这将允许您标记比使用文本标签稍多的异常值,同时仍然保持绘图相当容易访问。但是,如果附近有多个点,它也会失败。

【讨论】:

    【解决方案2】:

    它在 matplotlib 中:

    import numpy as np
    from matplotlib import pyplot, cm
    from mpl_toolkits.mplot3d import Axes3D
    
    data = np.genfromtxt('genes.txt', usecols=range(1,4))
    N = len(data)
    nout = N/4   # top 25% in magnitude
    outliers = np.argsort(np.sqrt(np.sum(data**2, 1)))[-nout:]
    outlies = np.zeros(N)
    outlies[outliers] = 1   # now an array of 0 or 1, depending on whether an outlier
    
    fig = pyplot.figure()
    ax = fig.add_subplot(111, projection='3d')
    
    ax.scatter(*data.T, c=cm.jet(outlies)) # color by whether outlies.
    pyplot.show()
    

    在这里,红色远离原点,蓝色靠近:

    【讨论】:

    • 谢谢,您能否也添加一行以获取这些异常值的列表。
    • @Angelo outliers 已经是异常值列表。如果您愿意,可以向print outliers 添加一行。您的数据集从gene1 开始计数,但异常值从0 开始计数。所以,你实际上想要print outliers + 1
    猜你喜欢
    • 2020-02-01
    • 1970-01-01
    • 2022-01-13
    • 1970-01-01
    • 2020-07-29
    • 2019-09-30
    • 2015-05-09
    • 2015-06-06
    • 2016-02-29
    相关资源
    最近更新 更多