es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Crear una tercera curva a partir de otras dos usando Python.

Tengo dos listas de coordenadas xy, que uso para trazar dos curvas. Estoy interesado en el área sobre las curvas, así que usé fill_between para obtener esto:

Ahora, lo que quiero es encontrar una forma de obtener las coordenadas que no están cubiertas por las áreas coloreadas, para luego trazar una tercera curva como la roja que hice utilizando Paint en el ejemplo de abajo:

He intentado ordenar las listas y luego comparar cada par para encontrar aquellos con valores de y más bajos, pero eso no funciona porque cada lista puede tener diferentes tamaños y diferentes valores de x. También encontré un par de hilos sobre productos cruzados, pero esos se basaban en líneas rectas y no logré entender cómo podía aplicarse a mi caso.

Aquí hay un ejemplo mínimo y completo:

import matplotlib.pyplot as plt

points_x = [1,3,5,7,9,11,13,15,17,19]
points_y = [10,8,7,6,3,5,3,9,7,6]
points_x2= [0,2,4,8,10,12,14,15,17,19,20,21,22]
points_y2 = [12,10,9,4,2,7,3,8,8,8,8,8,8]

plt.scatter(points_x, points_y, color="blue")
plt.scatter(points_x2, points_y2, color="green")

plt.fill_between(points_x, points_y, plt.ylim()[1], color='blue', alpha=0.5)
plt.fill_between(points_x2, points_y2, plt.ylim()[1], color='green', alpha=0.5)

#forma de obtener points_x3/points_y3 con solo las coordenadas en el borde de las áreas superpuestas

plt.show()

(Tuve problemas para encontrar los términos correctos para definir mi problema (no soy hablante nativo y no estoy acostumbrado a mucha terminología matemática), así que pido disculpas si estoy haciendo una pregunta duplicada)

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Un enfoque para obtener las coordenadas que no están cubiertas por las áreas coloreadas es utilizar la biblioteca numpy para crear una cuadrícula de coordenadas que cubra todo el gráfico, y luego utilizar la función contains_point() de la clase Path en matplotlib para determinar qué puntos no están en las áreas coloreadas.

    Aquí tienes un ejemplo de implementación de este enfoque basado en el código proporcionado:

    import numpy as np
    import matplotlib.pyplot as plt
    from matplotlib.path import Path
    
    points_x = [1,3,5,7,9,11,13,15,17,19]
    points_y = [10,8,7,6,3,5,3,9,7,6]
    points_x2 = [0,2,4,8,10,12,14,15,17,19,20,21,22]
    points_y2 = [12,10,9,4,2,7,3,8,8,8,8,8,8]
    
    fig, ax = plt.subplots()
    
    # trazar los puntos y las áreas rellenas
    ax.scatter(points_x, points_y, color='blue')
    ax.scatter(points_x2, points_y2, color='green')
    ax.fill_between(points_x, points_y, ax.get_ylim()[1], color='blue', alpha=0.5)
    ax.fill_between(points_x2, points_y2, ax.get_ylim()[1], color='green', alpha=0.5)
    
    # crear una cuadrícula de coordenadas que cubra todo el gráfico
    x_min, x_max = ax.get_xlim()
    y_min, y_max = ax.get_ylim()
    xx, yy = np.meshgrid(np.linspace(x_min, x_max, 100), np.linspace(y_min, y_max, 100))
    coords = np.column_stack((xx.ravel(), yy.ravel()))
    
    # crear un objeto de ruta para cada área rellena
    path1 = Path(np.column_stack((points_x, points_y)))
    path2 = Path(np.column_stack((points_x2, points_y2)))
    
    # determinar qué puntos de la cuadrícula no están en las áreas rellenas
    mask1 = path1.contains_points(coords)
    mask2 = path2.contains_points(coords)
    mask = np.logical_not(np.logical_or(mask1, mask2))
    
    # extraer las coordenadas x e y de los puntos de la cuadrícula no rellenos
    points_x3, points_y3 = coords[mask].T
    
    # trazar los puntos no rellenos como una curva roja
    ax.plot(points_x3, points_y3, color='red')
    
    plt.show()
    

    Este código crea una cuadrícula de 100×100 puntos que cubre todo el gráfico, y luego verifica qué puntos están dentro de las áreas rellenas azules y verdes utilizando la función contains_points() de la clase Path. Luego crea una máscara booleana que es True para los puntos de la cuadrícula que no están en ninguna de las áreas rellenas, y utiliza esta máscara para extraer las coordenadas x e y de estos puntos. Finalmente, traza estos puntos como una curva roja. El gráfico resultante se ve así:

    [![enter image description here][1]][1]

    Ten en cuenta que este enfoque asume que las áreas rellenas son continuas y no tienen ningún agujero. Si las áreas rellenas tienen agujeros, es posible que debas utilizar un enfoque diferente, como utilizar un histograma 2D para contar el número de puntos en cada área rellena y luego encontrar los límites entre las dos áreas basado en las cuentas del histograma.

Comments are closed.