[英]Drawing a FacetGrid of QQ-plots with seaborn
I am unable to draw a FacetGrid of QQ-plots with seaborn .我无法使用seaborn绘制QQ 图的FacetGrid 。
I have a matrix of m rows (observations) and n columns (features), and I want to draw a QQ-plot for each feature (column) to compare it with the normal distribution.我有一个 m 行(观察值)和 n 列(特征)的矩阵,我想为每个特征(列)绘制一个 QQ 图以将其与正态分布进行比较。
So far, my code is like this:到目前为止,我的代码是这样的:
import scipy.stats as ss
def qqplots(fpath, expr, title):
def quantile_plot(x, **kwargs):
x = ss.zscore(x)
qntls, xr = ss.probplot(x, dist="norm")
plt.scatter(xr, qntls, **kwargs)
expr_m = pd.melt(expr)
expr_m.columns = ["Feature", "Value"]
n_feat = len(expr_m["Feature"].value_counts().index)
n_cols = int(np.sqrt(n_feat)) + 1
g = sns.FacetGrid(expr_m, col="Feature", col_wrap=n_cols)
g.map(quantile_plot, "Value");
plt.savefig(fpath + ".pdf", bbox_inches="tight")
plt.savefig(fpath + ".png", bbox_inches="tight")
plt.close()
qqplots("lognorm_qqplot", np.log2(expr), "Log-normal qqplot")
The expr
variable is a pandas DataFrame with m rows (observations) and n columns (features). expr
变量是一个 pandas DataFrame,有 m 行(观察值)和 n 列(特征)。
The Exception I get is the following:我得到的异常如下:
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-52-f9333a55702e> in <module>()
39 plt.close()
40
---> 41 qqplots("lognorm_qqplot", np.log2(expr), "Log-normal qqplot")
<ipython-input-52-f9333a55702e> in qqplots(fpath, expr, title)
34
35 g = sns.FacetGrid(expr_m, col="Feature", col_wrap=n_cols)
---> 36 g.map(quantile_plot, "Value");
37 plt.savefig(fpath + ".pdf", bbox_inches="tight")
38 plt.savefig(fpath + ".png", bbox_inches="tight")
/usr/local/lib/python3.5/site-packages/seaborn/axisgrid.py in map(self, func, *args, **kwargs)
726
727 # Draw the plot
--> 728 self._facet_plot(func, ax, plot_args, kwargs)
729
730 # Finalize the annotations and layout
/usr/local/lib/python3.5/site-packages/seaborn/axisgrid.py in _facet_plot(self, func, ax, plot_args, plot_kwargs)
810
811 # Draw the plot
--> 812 func(*plot_args, **plot_kwargs)
813
814 # Sort out the supporting information
<ipython-input-52-f9333a55702e> in quantile_plot(y, **kwargs)
25 y = ss.zscore(y)
26 qntls, xr = ss.probplot(y, dist="norm")
---> 27 plt.scatter(xr, qntls, **kwargs)
28
29 expr_m = pd.melt(expr)
/usr/local/lib/python3.5/site-packages/matplotlib/pyplot.py in scatter(x, y, s, c, marker, cmap, norm, vmin, vmax, alpha, linewidths, verts, edgecolors, hold, data, **kwargs)
3249 vmin=vmin, vmax=vmax, alpha=alpha,
3250 linewidths=linewidths, verts=verts,
-> 3251 edgecolors=edgecolors, data=data, **kwargs)
3252 finally:
3253 ax.hold(washold)
/usr/local/lib/python3.5/site-packages/matplotlib/__init__.py in inner(ax, *args, **kwargs)
1810 warnings.warn(msg % (label_namer, func.__name__),
1811 RuntimeWarning, stacklevel=2)
-> 1812 return func(ax, *args, **kwargs)
1813 pre_doc = inner.__doc__
1814 if pre_doc is None:
/usr/local/lib/python3.5/site-packages/matplotlib/axes/_axes.py in scatter(self, x, y, s, c, marker, cmap, norm, vmin, vmax, alpha, linewidths, verts, edgecolors, **kwargs)
3838 y = np.ma.ravel(y)
3839 if x.size != y.size:
-> 3840 raise ValueError("x and y must be the same size")
3841
3842 s = np.ma.ravel(s) # This doesn't have to match x, y in size.
ValueError: x and y must be the same size
I achieved this, and also changed the color to use the Seaborn color palette, with the following code: 我做到了这一点,还通过以下代码将颜色更改为使用Seaborn调色板:
def qqplots(fpath, expr, title):
def quantile_plot(x, **kwargs):
x = ss.zscore(x)
ss.probplot(x, plot=plt)
expr_m = pd.melt(expr)
expr_m.columns = ["Feature", "Value"]
n_feat = len(expr_m["Feature"].value_counts().index)
n_cols = int(np.sqrt(n_feat)) + 1
g = sns.FacetGrid(expr_m, col="Feature", col_wrap=n_cols)
g.map(quantile_plot, "Value");
for ax in g.axes:
ax.get_lines()[0].set_markerfacecolor(sns.color_palette()[0])
ax.get_lines()[1].set_color(sns.color_palette()[3])
plt.savefig(fpath + ".pdf", bbox_inches="tight")
plt.savefig(fpath + ".png", bbox_inches="tight")
plt.close()
qqplots("lognorm_qqplot", np.log2(expr), "Log-normal qqplot")
Answering your question: "I am unable to draw a FacetGrid of QQ-plots with seaborn.", I give you here an example with dataset tips
from seaborn
.回答你的问题:“我无法用 seaborn 绘制 QQ 图的 FacetGrid。”,我在这里给你一个来自
seaborn
的数据集tips
的例子。
To draw qqplots, one of the best approaches is to use the statsmodels
library which has the qqplot function built into it.要绘制 qqplots,最好的方法之一是使用内置了qqplot function 的
statsmodels
库。 This function generates a new figure if the given ax
is not passed as an argument.如果给定的
ax
未作为参数传递,则此 function 会生成一个新图形。 Therefore, using FacetGrid.map()
with this function generates individual figures instead of plotting everything on the grid.因此,将
FacetGrid.map()
与此 function 一起使用会生成单独的图形,而不是在网格上绘制所有内容。 To deal with this, you can use a user-defined function in which sm.qqplots
retrieves the current ax
thanks to plt.gca()
.为了解决这个问题,您可以使用用户定义的 function ,其中
sm.qqplots
通过plt.gca()
检索当前ax
。 Here I created a new function called qqplot_new
.在这里,我创建了一个名为
qqplot_new
。 Here the qqplots are like test for normality of data.这里的 qqplots 就像测试数据的正态性。
from matplotlib import pyplot as plt
import seaborn as sns
import statsmodels.api as sm
tips = sns.load_dataset("tips")
def qqplot_new(x, ax=None, **kwargs):
if ax is None:
ax = plt.gca()
sm.qqplot(x, ax=ax, **kwargs)
g = sns.FacetGrid(tips, col="time", row="sex")
g.map(qqplot_new, "total_bill", line='s')
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.