xlabel set_xticks set_xlabel font python matplotlib histogram bins

python - set_xlabel - set_xticks



Histograma de matplotlib con bandeja de recolección para valores altos (2)

Lo siento, no estoy familiarizado con matplotlib. Así que tengo un truco sucio para ti. Acabo de poner todos los valores mayores de 300 en una bandeja y cambié el tamaño de la bandeja.

La raíz del problema es que matplotlib intenta poner todos los contenedores en la trama. En RI convertiría mis contenedores a la variable factor, por lo que no se tratan como números reales.

import matplotlib.pyplot as plt import numpy as np def plot_histogram_01(): np.random.seed(1) values_A = np.random.choice(np.arange(600), size=200, replace=True).tolist() values_B = np.random.choice(np.arange(600), size=200, replace=True).tolist() values_A_to_plot = [301 if i > 300 else i for i in values_A] values_B_to_plot = [301 if i > 300 else i for i in values_B] bins = [0, 25, 50, 75, 100, 125, 150, 175, 200, 225, 250, 275, 300, 325] fig, ax = plt.subplots(figsize=(9, 5)) _, bins, patches = plt.hist([values_A_to_plot, values_B_to_plot], normed=1, # normed is deprecated and will be replaced by density bins=bins, color=[''#3782CC'', ''#AFD5FA''], label=[''A'', ''B'']) xlabels = np.array(bins[1:], dtype=''|S4'') xlabels[-1] = ''300+'' N_labels = len(xlabels) plt.xticks(25 * np.arange(N_labels) + 12.5) ax.set_xticklabels(xlabels) plt.yticks([]) plt.title('''') plt.setp(patches, linewidth=0) plt.legend() fig.tight_layout() plt.savefig(''my_plot_01.png'') plt.close() plot_histogram_01()

Tengo una matriz con valores, y quiero crear un histograma de la misma. Estoy interesado principalmente en los números de gama baja, y quiero recopilar todos los números de más de 300 en una ubicación. Esta bandeja debe tener el mismo ancho que todas las demás bandejas (igualmente anchas). ¿Cómo puedo hacer esto?

Nota: esta pregunta está relacionada con esta pregunta: Definición del ancho del contenedor / escala del eje x en el histograma de Matplotlib

Esto es lo que intenté hasta ahora:

import matplotlib.pyplot as plt import numpy as np def plot_histogram_01(): np.random.seed(1) values_A = np.random.choice(np.arange(600), size=200, replace=True).tolist() values_B = np.random.choice(np.arange(600), size=200, replace=True).tolist() bins = [0, 25, 50, 75, 100, 125, 150, 175, 200, 225, 250, 275, 300, 600] fig, ax = plt.subplots(figsize=(9, 5)) _, bins, patches = plt.hist([values_A, values_B], normed=1, # normed is deprecated and will be replaced by density bins=bins, color=[''#3782CC'', ''#AFD5FA''], label=[''A'', ''B'']) xlabels = np.array(bins[1:], dtype=''|S4'') xlabels[-1] = ''300+'' N_labels = len(xlabels) plt.xlim([0, 600]) plt.xticks(25 * np.arange(N_labels) + 12.5) ax.set_xticklabels(xlabels) plt.yticks([]) plt.title('''') plt.setp(patches, linewidth=0) plt.legend() fig.tight_layout() plt.savefig(''my_plot_01.png'') plt.close()

Este es el resultado, que no se ve bien:

Entonces cambié la línea con xlim en ella:

plt.xlim([0, 325])

Con el siguiente resultado:

Se ve más o menos como lo quiero, pero la última bandeja no está visible ahora. ¿Qué truco me falta para visualizar este último contenedor con un ancho de 25?


Numpy tiene una función práctica para tratar esto: np.clip . A pesar de cómo suena el nombre, no elimina los valores, solo los limita al rango que usted especifique. Básicamente, lo hace el "hackeo sucio" de Artem en línea. Puede dejar los valores como están, pero en la llamada hist , simplemente envuelva la matriz en una llamada np.clip , como

plt.hist(np.clip(values_A, bins[0], bins[-1]), bins=bins)

Esto es mejor por varias razones:

  1. Es mucho más rápido, al menos para grandes cantidades de elementos. Numpy hace su trabajo en el nivel C. Operar en listas de python (como en la lista de comprensión de Artem) tiene muchos gastos generales para cada elemento. Básicamente, si alguna vez tienes la opción de usar numpy, deberías.

  2. Lo hace justo donde lo necesita, lo que reduce la posibilidad de cometer errores en su código.

  3. No necesita mantener una segunda copia de la matriz colgada, lo que reduce el uso de la memoria (excepto dentro de esta línea) y reduce aún más las posibilidades de cometer errores.

  4. Al usar bins[0], bins[-1] lugar de codificar los valores, se reducen las posibilidades de cometer errores nuevamente, porque puede cambiar los bins justo donde se definieron los bins ; no es necesario recordar cambiarlos en la llamada a clip o en cualquier otro lugar.

Así que para ponerlo todo junto como en el OP:

import matplotlib.pyplot as plt import numpy as np def plot_histogram_01(): np.random.seed(1) values_A = np.random.choice(np.arange(600), size=200, replace=True) values_B = np.random.choice(np.arange(600), size=200, replace=True) bins = np.arange(0,350,25) fig, ax = plt.subplots(figsize=(9, 5)) _, bins, patches = plt.hist([np.clip(values_A, bins[0], bins[-1]), np.clip(values_B, bins[0], bins[-1])], # normed=1, # normed is deprecated; replace with density density=True, bins=bins, color=[''#3782CC'', ''#AFD5FA''], label=[''A'', ''B'']) xlabels = bins[1:].astype(str) xlabels[-1] += ''+'' N_labels = len(xlabels) plt.xlim([0, 325]) plt.xticks(25 * np.arange(N_labels) + 12.5) ax.set_xticklabels(xlabels) plt.yticks([]) plt.title('''') plt.setp(patches, linewidth=0) plt.legend(loc=''upper left'') fig.tight_layout() plot_histogram_01()