matplotlib: ignorar los valores atípicos al trazar

Estoy trazando algunos datos de varias pruebas. Algunas veces, en una prueba, tengo un valor atípico (por ejemplo, 0.1), mientras que todos los demás valores son tres órdenes de magnitud más pequeños.

Con matplotlib, grafico contra el rango [0, max_data_value]

¿Cómo puedo hacer zoom en mis datos y no mostrar valores atípicos, lo que podría estropear el eje x en mi gráfico?

¿Debería simplemente tomar el percentil 95 y tener el rango [0, 95_percentile] en el eje x?

    No hay una única “mejor” prueba para un valor atípico. Idealmente, debería 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 la varianza. De lo contrario, la variación / stddev que se calcula estará fuertemente 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() 

    introduzca la descripción de la imagen aquí

    Si no está preocupado por rechazar los valores atípicos mencionados por Joe y son razones puramente estéticas para hacer esto, puede establecer los límites del eje x de su gráfico:

     plt.xlim(min_x_data_value,max_x_data_value) 

    Donde los valores son los límites que desea visualizar.

    plt.ylim(min,max) trabaja para establecer límites en el eje y.