Columna blanca no deseada en matplotlib - cómo quitar?
aquí está el código de pitón (portando del excelente Repensamiento Estadístico de Richard McElreath) que resulta en un 'column' transparente blanco no deseado en mi trama resultante:
import numpy as np
import pandas as pd
import scipy.stats
import matplotlib.pyplot as plt
# import data
url = "https://raw.githubusercontent.com/pymc-devs/resources/master/Rethinking_2/Data/Howell1.csv"
df = pd.read_csv(url, delimiter = ';')
df2 = df[df.age >= 18]
# sample priors (prior predictive check)
n = 100
a = scipy.stats.norm.rvs(178, 20, n)
b1 = scipy.stats.norm.rvs(0, 10, n)
b2 = np.exp(scipy.stats.norm.rvs(0, 1, n))
xbar = df2.weight.mean()
# compare 2 priors
fig,ax = plt.subplots(1,2,sharey=True)
for i in range(100):
ax[0].plot(df2.weight, a[i] + b1[i]*(df2.weight - xbar),color = 'grey',lw=.5,alpha=.2)
ax[0].set_xlabel('weight')
ax[0].set_ylabel('height')
ax[0].set_title('normal prior of β')
ax[1].plot(df2.weight, a[i] + b2[i]*(df2.weight - xbar),color = 'grey',lw=.5,alpha=.2)
ax[1].set_xlabel('weight')
ax[1].set_title('log-normal prior of β')
plt.axis([30,60,-100,400])
plt.show()
Esto ocurre en mi cuaderno Jupyter, en Google CoLab y en el pdf (plt.savefig)
Mis versiones de notebook: numposo 1.19.4 pandas 1.1.5 disciplina 1.5.4 matplotlib 3.3.3
¡Gracias!
Pregunta hecha hace 3 años, 4 meses, 28 días - Por nasean
5 Respuestas:
-
Creo que te refieres a la región donde las líneas se dibujan más delgadas y no las fronteras.
Descubrí que tiene que ver con el aliado y no con los datos mismos.
Jugar alrededor con el antialiased parámetro:
ax[0].plot(..., antialiased=False)
Parece que esto:
Seguramente hace que la trama parezca fea pero puede aumentar el tamaño de la figura o el parámetro dpi.
fig.set_dpi(300.0) ... plt.show();
Entonces tienes esto:
Respondida el Dec 17, 2020 a las 15:17 - por cybermage
Votos positivos: 0 | Votos negativos: 0 -
Este es un artefacto de datos que interactúa con el anti-aliasing de una manera interesante. En la imagen final tenemos que elegir un color para cada pixel. Sin anti-aliasing cuando tenemos que dibujar una línea tenemos que decidir es este pixel "en" la línea (y por lo tanto la coloramos) o "out" (en cuyo caso no la coloramos) que puede conducir a líneas de aspecto escalera (en particular con líneas que son cerca a plana). Con anti-aliasing coloramos el píxel basado en cuánto del píxel está "en" la línea vs no. Esa mirada nos engaña (de buena manera) y vemos una línea recta más convincente. Sin anti-aliasing o alfa dibujando la misma línea varias veces no cambia la apariencia (cualquier pixel dado está todavía dentro o fuera), pero con anti-aliasing o alfa, cada vez que dibuja la línea cualquiera de los píxeles "partiales" se vuelve más oscuro.
En los datos originales los valores
df2.weight
todos caen en la misma línea, pero no están ordenados de modo que lo dibujamos va de vuelta a adelante sobre el mismo camino (ver el rastro en el panel del centro izquierdo). Dependiendo de exactamente dónde están los puntos de inflexión y cuántas veces cualquier segmento dado se atraviesa la línea se verá más oscura en algunos lugares que otros. Hay algo en la estructura exacta de los datos que está causando ese "banda".Si aumentas el DPI, los píxeles se vuelven más pequeños para que el efecto se pronuncie menos (similar a ampliar) y si giras de anti-aliasing el efecto se hará menos pronunciado. Sospecho (pero no lo han probado) si usted elimina los datos que usted será capaz de mover la banda alrededor!
Clasificación de los pesos (que desde este contexto no creo que su orden sea significativo?) hace las parcelas en los dos paneles inferiores que se ven más agradables.
Así que en resumen, esa banda es "real" en el sentido de que representa algo en los datos en lugar de ser un error en el proceso de renderizado, pero está resaltando la estructura en los datos que no creo que sea significativo.
import numpy as np import pandas as pd import scipy.stats import matplotlib.pyplot as plt # import data url = "https://raw.githubusercontent.com/pymc-devs/resources/master/Rethinking_2/Data/Howell1.csv" # this is a mpl 3.3 feature fig, ad = plt.subplot_mosaic( [ ["normal", "log-normal"], ["trace", "hist"], ["sorted normal", "sorted log-normal"], ], constrained_layout=True, ) df = pd.read_csv(url, delimiter=";") df2 = df[df.age >= 18] # sample priors (prior predictive check) n = 100 a = scipy.stats.norm.rvs(178, 20, n) b1 = scipy.stats.norm.rvs(0, 10, n) b2 = np.exp(scipy.stats.norm.rvs(0, 1, n)) def inner(weights, a, b1, b2, ax_dict): xbar = np.mean(weights) for i in range(100): ax_dict["normal"].plot( weights, a[i] + b1[i] * (weights - xbar), color="grey", lw=0.5, alpha=0.2 ) ax_dict["normal"].set_xlabel("weight") ax_dict["normal"].set_ylabel("height") ax_dict["normal"].set_title("normal prior of β") ax_dict["log-normal"].plot( weights, a[i] + b2[i] * (weights - xbar), color="grey", lw=0.5, alpha=0.2 ) ax_dict["log-normal"].set_xlabel("weight") ax_dict["log-normal"].set_title("log-normal prior of β") inner(df2.weight, a, b1, b2, ad) inner( np.array(sorted(df2.weight)), a, b1, b2, {"normal": ad["sorted normal"], "log-normal": ad["sorted log-normal"]}, ) ad["hist"].hist(df2.weight, bins=100, color="0.5") ad["hist"].set_xlabel("weight") ad["hist"].set_ylabel("#") ad["trace"].plot(df2.weight, "-o", color="0.5", alpha=0.5) ad["trace"].set_ylabel("weight") ad["trace"].set_xlabel("index") plt.show()
Respondida el Dec 17, 2020 a las 15:22 - por hackharbinger
Votos positivos: 0 | Votos negativos: 0 -
Fijo los valores manualmente, pero si fijas los ejes para cada gráfico, los márgenes desaparecerán.
ax[0].axis([33,63,-100,400]) ax[1].axis([33,60,-100,400])
Si quieres que el espaciado entre los gráficos sea más estrecho, puedes hacerlo de la siguiente manera.
fig.subplots_adjust(wspace=0.05)
Respondida el Dec 17, 2020 a las 15:29 - por syntaxsniper
Votos positivos: 0 | Votos negativos: 0 -
El problema que estás experimentando con la presencia de esas columnas blancas en tu gráfica es debido a cómo estás realizando el bucle en tu código. El problema radica en que estás configurando las etiquetas de los ejes y títulos por cada iteración dentro del bucle, lo cual provoca que se superpongan y resulten en la aparición de las columnas blancas no deseadas en tu gráfico.
Para solucionarlo, debes mover las líneas donde se configuran las etiquetas de los ejes y títulos fuera del bucle
for i in range(100):
. De esta forma, estas configuraciones se realizarán una sola vez y no se repetirán en cada iteración del bucle, evitando así el problema de las columnas blancas.Aquí te dejo el código modificado:
```python import numpy as np import pandas as pd import scipy.stats
import matplotlib.pyplot as plt
import data
url = "https://raw.githubusercontent.com/pymc-devs/resources/master/Rethinking_2/Data/Howell1.csv"df = pd.read_csv(url, delimiter=';') df2 =
Respondida el Dec 18, 2020 a las 15:16 - por Gpt
Votos positivos: 0 | Votos negativos: 0 -
La columna blanca no deseada en tu trama de Matplotlib es causada por el uso de
ax.plot()
para dibujar las líneas de regresión.ax.plot()
dibuja una línea entre cada par de puntos en tus datos, y en este caso, estás proporcionando solo un conjunto de valores y (los pesos) y sin valores x. Esto hace queax.plot()
conecte cada peso con el siguiente, creando la línea vertical.Para solucionar este problema, debes proporcionar valores x para tus líneas de regresión. En este caso, puedes usar los pesos como valores x:
python for i in range(100): ax[0].plot(df2.weight, a[i] + b1[i](df2.weight - xbar),color = 'grey',lw=.5,alpha=.2) ax[0].set_xlabel('weight') ax[0].set_ylabel('height') ax[0].set_title('normal prior of β') ax[1].plot(df2.weight, a[i] + b2[i](df2.weight - xbar),color = 'grey',lw=.5,alpha=.2) ax[1].set_xlabel('weight') ax[1].set_title('log-normal prior of β')
También puedes utilizar la función
ax.scatter()
para dibujar las líneas de regresión.ax.scatter()
dibuja un punto para cada par de valores x e y, y no conectará los puntos.python for i in range(100): ax[0].scatter(df2.weight, a[i] + b1[i](df2.weight - xbar),color = 'grey',lw=.5,alpha=.2) ax[0].set_xlabel('weight') ax[0].set_ylabel('height') ax[0].set_title('normal prior of β') ax[1].scatter(df2.weight, a[i] + b2[i](df2.weight - xbar),color = 'grey',lw=.5,alpha=.2) ax[1].set_xlabel('weight') ax[1].set_title('log-normal prior of β')
Ambos métodos deberían eliminar la columna blanca no deseada de tu trama.
Respondida el Dec 18, 2020 a las 15:17 - por Gemini
Votos positivos: 0 | Votos negativos: 0