python - multiple - matplotlib: haga caso omiso de valores atípicos al trazar
plot() python (2)
Estoy tramando algunos datos de varias pruebas. A veces, en una prueba, tengo un valor atípico (digamos 0.1), mientras que todos los demás valores son tres órdenes de magnitud más pequeños.
Con matplotlib, tramo contra el rango [0, max_data_value]
¿Cómo puedo hacer zoom en mis datos y no mostrar valores atípicos, lo que estropearía el eje x en mi trama?
¿Debería simplemente tomar el percentil 95 y tener el rango [0, 95_percentile]
en el eje x?
Si no te preocupas por rechazar valores atípicos como lo menciona Joe y hay razones puramente estéticas para hacerlo, puedes establecer los límites del eje x de tu gráfica:
plt.xlim(min_x_data_value,max_x_data_value)
Donde los valores son los límites deseados para mostrar.
plt.ylim(min,max)
trabaja para establecer límites en el eje y.
No hay una sola "mejor" prueba para un valor atípico. Idealmente, debe incorporar información a priori (por ejemplo, "Este parámetro no debe estar sobre x debido a bla ...").
La mayoría de las pruebas para valores atípicos utilizan la desviación absoluta media, en lugar del percentil 95 o alguna otra medida basada en varianza. De lo contrario, la varianza / stddev que se calcula estará muy sesgada por los valores atípicos.
Aquí hay una función que implementa una de las pruebas atípicas más comunes.
def is_outlier(points, thresh=3.5):
"""
Returns a boolean array with True if points are outliers and False
otherwise.
Parameters:
-----------
points : An numobservations by numdimensions array of observations
thresh : The modified z-score to use as a threshold. Observations with
a modified z-score (based on the median absolute deviation) greater
than this value will be classified as outliers.
Returns:
--------
mask : A numobservations-length boolean array.
References:
----------
Boris Iglewicz and David Hoaglin (1993), "Volume 16: How to Detect and
Handle Outliers", The ASQC Basic References in Quality Control:
Statistical Techniques, Edward F. Mykytka, Ph.D., Editor.
"""
if len(points.shape) == 1:
points = points[:,None]
median = np.median(points, axis=0)
diff = np.sum((points - median)**2, axis=-1)
diff = np.sqrt(diff)
med_abs_deviation = np.median(diff)
modified_z_score = 0.6745 * diff / med_abs_deviation
return modified_z_score > thresh
Como ejemplo de uso, harías algo como lo siguiente:
import numpy as np
import matplotlib.pyplot as plt
# The function above... In my case it''s in a local utilities module
from sci_utilities import is_outlier
# Generate some data
x = np.random.random(100)
# Append a few "bad" points
x = np.r_[x, -3, -10, 100]
# Keep only the "good" points
# "~" operates as a logical not operator on boolean numpy arrays
filtered = x[~is_outlier(x)]
# Plot the results
fig, (ax1, ax2) = plt.subplots(nrows=2)
ax1.hist(x)
ax1.set_title(''Original'')
ax2.hist(filtered)
ax2.set_title(''Without Outliers'')
plt.show()