Python: el diagrama de dispersión R obtiene valores debajo de la curva

CorePress2024-01-24  9

R diagrama de dispersión y creé las tres líneas curvas y quería valores que estén cubiertos por las dos líneas exteriores

sugiérame cómo puedo obtener los valores que están entre las dos líneas rojas exteriores

datos utilizados datos de prueba

código utilizado

library("PerformanceAnalytics")


df=read.table("test",sep='\t', header=TRUE)
pdf('test.pdf',width=6,height=6)
smoothScatter(df$level2,df$level1,main = "data",xlab='level2',ylab='level1',nrpoints=Inf,xlim=c(0,1),ylim=c(0,1),pch=20,cex=0.5)
points(c(0,1),c(1,0),type='l',col='green',lty=2,lwd=2)
points(((1-p)^2)+0.03,(p^2)+0.03,type='l',col='red',lty=2,lwd=2)
points(((1-p)^2)-0.03,(p^2)-0.03,type='l',col='red',lty=2,lwd=2)
p=0:1000/1000
points((1-p)^2,p^2,type='l',col='red',lty=2,lwd=2)
legend(0.30, 1, c("Co", "data_observe"), 
       col = c("green", "red"), bg = "#FFFFFFAA", 
       lty = 2, lwd = 4, box.col = "#FFFFFF00")
dev.off()

Gracias

Atrevido de tu parte etiquetar una pregunta de R con Python

Pietro

27/03/2021 a las 10:20

@Pietro Pensé que con algún filtro de datos viendo los valores de la curva se pueden filtrar, con Python

- Sardar afortunado

27/03/2021 a las 10:29

No sé cómo integrar los dos lenguajes, pero si tienes una fórmula de forma cerrada para las líneas rojas, puedes calcular para cada punto de datos los valores ylow y yhigh para las dos líneas usando el valor x del punto de datos y luego verifique si el valor de datos y está entre esos dos.

Pietro

27 de marzo de 2021 a las 10:30

@Pietro Lo intenté pero no pude conseguirlo. ¿Puedes mostrarlo con algún código?

- Sardar afortunado

27/03/2021 a las 10:40

Si no estás intentando identificar automáticamente los puntos, pero puedes hacerlo de forma interactiva, intenta identificar().

- dcarlson

27/03/2021 a las 15:44



------------------------------------

Esto es lo que quise decir:

Calcula la forma cerrada de la frontera, y=f(x), resolviendo para p. Para cada punto, calcula los valores de los límites para ese valor de x. Compruebe si el valor de y para ese punto está entre los límites calculados. Utilice este resultado para crear una variedad de colores, uno por punto.

Todos juntos:

import csv
import matplotlib.pyplot as plt
from pathlib import Path
import numpy as np


def limsup(x):
    alpha = 0.03
    return (1 - np.sqrt(x - alpha)) ** 2 + alpha


def liminf(x):
    alpha = -0.03
    return (1 - np.sqrt(x - alpha)) ** 2 + alpha


fig, ax = plt.subplots(1, 1)

data_name = "testdata.tsv"
data_path = Path(data_name)

l1, l2 = [], []
between = []

with data_path.open() as dp_f:
    data_tsv = csv.reader(dp_f, delimiter="\t")
    next(data_tsv)
    for row in data_tsv:
        l1val = float(row[1])
        l1.append(l1val)
        l2val = float(row[2])
        l2.append(l2val)

        # compute the values of the two boundary for this x value
        sup = limsup(l2val)
        inf = liminf(l2val)

        # if the y value is between the boundary, assing green
        if inf <= l1val <= sup:
            between.append("green")
        else:
            between.append("blue")

ax.scatter(l2, l1, c=between, marker=".", label="data")

p = np.linspace(0, 1, 100)

# just to check that the limsup/liminf are correct
# ax.plot((1 - p) ** 2, p ** 2)
# ax.plot((1 - p) ** 2 + 0.03, p ** 2 + 0.03, label="sup")
# ax.plot((1 - p) ** 2 - 0.03, p ** 2 - 0.03, label="inf")

ax.plot(p, np.fromiter((limsup(x) for x in p), dtype=float), label="limsup")
ax.plot(p, np.fromiter((liminf(x) for x in p), dtype=float), label="liminf")

ax.legend()
fig.tight_layout()
plt.show()

Lo que produce esto:

No tengo idea de cómo portar esto a R, pero el razonamiento general debería ser claro.

¡Salud!

1

no es necesario transferir a R cómo obtener los valores de color verde

- Sardar afortunado

27/03/2021 a las 19:11



------------------------------------

Aquí hay un proceso automatizado que compara cada punto con las líneas rojas media e inferior. Habrá una advertencia de que el último valor en yvalu es NaN, pero puedes ignorarlo:

yvalm <- ((2 - sqrt(4 - 4 * (1 - df$level2)))/2)^2               # Middle Red Line
yvalu <- ((2 - sqrt(4 - 4 * (1 - df$level2 + .03)))/2)^2 + .03   # Upper Red Line
# Warning message:
# In sqrt(4 - 4 * (1 - df$level2 + 0.03)) : NaNs produced
yvall <- ((2 - sqrt(4 - 4 * (1 - df$level2 - .03)))/2)^2 - .03   # Lower Red Line
Within <- which(df$level1 > yvall & df$level1 < yvalm)
points(level1~level2, df[Within, ], cex=2, col="red")

El gráfico muestra los puntos identificados.

Ahora enumera los puntos:

df[Within, ]
#          data level1 level2
# 149  data2696 0.0813 0.4553
# 660  data3795 0.1393 0.3279
# 672  data3388 0.1789 0.3252
# 742   data536 0.1901 0.3140
# 1430 data1809 0.2750 0.1750
# 1455  data929 0.3220 0.1695
# 1722 data2306 0.4098 0.1230
# 1861  data362 0.4455 0.1000
# 2032  data559 0.5164 0.0574

La solución sugerida por @Pietro también es sencilla en R:

library(sp)
middle <- cbind((1 - p)^2, p^2)
lower <- cbind(rev((1 - p)^2 - 0.03), rev((p^2) - 0.03))
poly <- rbind(middle, lower)
polygon(poly)
inside <- point.in.polygon(df$level2, df$level1, poly[, 1], poly[, 2])
df[inside==1, ]
#          data level1 level2
# 149  data2696 0.0813 0.4553
# 660  data3795 0.1393 0.3279
# 672  data3388 0.1789 0.3252
# 742   data536 0.1901 0.3140
# 1430 data1809 0.2750 0.1750
# 1455  data929 0.3220 0.1695
# 1722 data2306 0.4098 0.1230
# 1861  data362 0.4455 0.1000
# 2032  data559 0.5164 0.0574

2

Gracias, pero el problema está en mis puntos de datos reales, hay muchos y me quitará mucho tiempo

- Sardar afortunado

27/03/2021 a las 19:09

He reemplazado la respuesta original con un enfoque diferente.

- dcarlson

28 de marzo de 2021 a las 2:49

Su guía para un futuro mejor - libreflare
Su guía para un futuro mejor - libreflare