如何将相关矩阵绘制为一组椭圆,类似于 R 露天包?
How can I plot a correlation matrix as a set of ellipses, similar to the R open-air package?
下图是使用open-air R包绘制的:
我知道 matplotlib 有 plt.matshow
函数,
但不能同时清楚地显示变量之间的关系。
这是我早期的作品:
df 是一个包含 7 个变量的 pandas 数据框,如下所示:
我不知道如何将 .csv
文件附加到 Whosebug。
使用plt.matshow(df.corr(),cmap = plt.cm.Greens)
,如图所示:
第二张图不能像第一张图那样清楚地表示变量的相关关系
编辑:
我将 csv 文件上传到 Google 文档 here。
假设你对显示集群关系感兴趣,评论中提到的seaborn
包也有一个clustermap。使用相关矩阵(看起来你想在 [-100, 100]
范围内将相关系数显示为 int
,你可以执行以下操作:
corr = df.corr().mul(100).astype(int)
GX HG RM SJ XB XN ZG
GX 100 77 62 71 48 66 57
HG 77 100 69 74 61 61 58
RM 62 69 100 75 48 64 68
SJ 71 74 75 100 50 70 65
XB 48 61 48 50 100 46 51
XN 66 61 64 70 46 100 75
ZG 57 58 68 65 51 75 100
然后使用seaborn.clustermap()
如下:
import seaborn as sns
sns.clustermap(data=corr, annot=True, fmt='d', cmap='Greens').savefig('cluster.png')
我不知道有任何现有的 Python 库可以执行这些 "ellipse plots",但使用 matplotlib.collections.EllipseCollection
:
实现起来并不是特别困难
import numpy as np
import pandas as pd
from matplotlib import pyplot as plt
from matplotlib.collections import EllipseCollection
def plot_corr_ellipses(data, ax=None, **kwargs):
M = np.array(data)
if not M.ndim == 2:
raise ValueError('data must be a 2D array')
if ax is None:
fig, ax = plt.subplots(1, 1, subplot_kw={'aspect':'equal'})
ax.set_xlim(-0.5, M.shape[1] - 0.5)
ax.set_ylim(-0.5, M.shape[0] - 0.5)
# xy locations of each ellipse center
xy = np.indices(M.shape)[::-1].reshape(2, -1).T
# set the relative sizes of the major/minor axes according to the strength of
# the positive/negative correlation
w = np.ones_like(M).ravel()
h = 1 - np.abs(M).ravel()
a = 45 * np.sign(M).ravel()
ec = EllipseCollection(widths=w, heights=h, angles=a, units='x', offsets=xy,
transOffset=ax.transData, array=M.ravel(), **kwargs)
ax.add_collection(ec)
# if data is a DataFrame, use the row/column names as tick labels
if isinstance(data, pd.DataFrame):
ax.set_xticks(np.arange(M.shape[1]))
ax.set_xticklabels(data.columns, rotation=90)
ax.set_yticks(np.arange(M.shape[0]))
ax.set_yticklabels(data.index)
return ec
例如,使用您的数据:
data = df.corr()
fig, ax = plt.subplots(1, 1)
m = plot_corr_ellipses(data, ax=ax, cmap='Greens')
cb = fig.colorbar(m)
cb.set_label('Correlation coefficient')
ax.margins(0.1)
负相关可以绘制为相反方向的椭圆:
fig2, ax2 = plt.subplots(1, 1)
data2 = np.linspace(-1, 1, 9).reshape(3, 3)
m2 = plot_corr_ellipses(data2, ax=ax2, cmap='seismic', clim=[-1, 1])
cb2 = fig2.colorbar(m2)
ax2.margins(0.3)
我今天才发现这个 Python 包 biokit。它提供了一个非常方便的功能来创建各种相关图表。例如:
In [1]: import pandas as pd
In [2]: import matplotlib.pyplot as plt
...: from biokit.viz import corrplot
In [6]: corr
Out[6]:
GX HG RM SJ XB XN ZG
GX 1.00 -0.77 0.62 0.71 0.48 0.66 0.57
HG -0.77 1.00 0.69 0.74 0.61 0.61 0.58
RM 0.62 0.69 1.00 0.75 0.48 0.64 0.68
SJ 0.71 0.74 0.75 1.00 0.50 0.70 0.65
XB 0.48 0.61 0.48 0.50 1.00 -0.46 0.51
XN 0.66 0.61 0.64 0.70 -0.46 1.00 0.75
ZG 0.57 0.58 0.68 0.65 0.51 0.75 1.00
我拿了Stefan的数据,稍微修改了一下。让我们假设这是一个相关矩阵。现在要创建相关图表,您可以简单地这样做:
In [7]: c = corrplot.Corrplot(corr)
...: c.plot()
Correlation chart with ellipses
您可以阅读更多示例here。
下图是使用open-air R包绘制的:
我知道 matplotlib 有 plt.matshow
函数,
但不能同时清楚地显示变量之间的关系。
这是我早期的作品:
df 是一个包含 7 个变量的 pandas 数据框,如下所示:
我不知道如何将 .csv
文件附加到 Whosebug。
使用plt.matshow(df.corr(),cmap = plt.cm.Greens)
,如图所示:
第二张图不能像第一张图那样清楚地表示变量的相关关系
编辑:
我将 csv 文件上传到 Google 文档 here。
假设你对显示集群关系感兴趣,评论中提到的seaborn
包也有一个clustermap。使用相关矩阵(看起来你想在 [-100, 100]
范围内将相关系数显示为 int
,你可以执行以下操作:
corr = df.corr().mul(100).astype(int)
GX HG RM SJ XB XN ZG
GX 100 77 62 71 48 66 57
HG 77 100 69 74 61 61 58
RM 62 69 100 75 48 64 68
SJ 71 74 75 100 50 70 65
XB 48 61 48 50 100 46 51
XN 66 61 64 70 46 100 75
ZG 57 58 68 65 51 75 100
然后使用seaborn.clustermap()
如下:
import seaborn as sns
sns.clustermap(data=corr, annot=True, fmt='d', cmap='Greens').savefig('cluster.png')
我不知道有任何现有的 Python 库可以执行这些 "ellipse plots",但使用 matplotlib.collections.EllipseCollection
:
import numpy as np
import pandas as pd
from matplotlib import pyplot as plt
from matplotlib.collections import EllipseCollection
def plot_corr_ellipses(data, ax=None, **kwargs):
M = np.array(data)
if not M.ndim == 2:
raise ValueError('data must be a 2D array')
if ax is None:
fig, ax = plt.subplots(1, 1, subplot_kw={'aspect':'equal'})
ax.set_xlim(-0.5, M.shape[1] - 0.5)
ax.set_ylim(-0.5, M.shape[0] - 0.5)
# xy locations of each ellipse center
xy = np.indices(M.shape)[::-1].reshape(2, -1).T
# set the relative sizes of the major/minor axes according to the strength of
# the positive/negative correlation
w = np.ones_like(M).ravel()
h = 1 - np.abs(M).ravel()
a = 45 * np.sign(M).ravel()
ec = EllipseCollection(widths=w, heights=h, angles=a, units='x', offsets=xy,
transOffset=ax.transData, array=M.ravel(), **kwargs)
ax.add_collection(ec)
# if data is a DataFrame, use the row/column names as tick labels
if isinstance(data, pd.DataFrame):
ax.set_xticks(np.arange(M.shape[1]))
ax.set_xticklabels(data.columns, rotation=90)
ax.set_yticks(np.arange(M.shape[0]))
ax.set_yticklabels(data.index)
return ec
例如,使用您的数据:
data = df.corr()
fig, ax = plt.subplots(1, 1)
m = plot_corr_ellipses(data, ax=ax, cmap='Greens')
cb = fig.colorbar(m)
cb.set_label('Correlation coefficient')
ax.margins(0.1)
负相关可以绘制为相反方向的椭圆:
fig2, ax2 = plt.subplots(1, 1)
data2 = np.linspace(-1, 1, 9).reshape(3, 3)
m2 = plot_corr_ellipses(data2, ax=ax2, cmap='seismic', clim=[-1, 1])
cb2 = fig2.colorbar(m2)
ax2.margins(0.3)
我今天才发现这个 Python 包 biokit。它提供了一个非常方便的功能来创建各种相关图表。例如:
In [1]: import pandas as pd
In [2]: import matplotlib.pyplot as plt
...: from biokit.viz import corrplot
In [6]: corr
Out[6]:
GX HG RM SJ XB XN ZG
GX 1.00 -0.77 0.62 0.71 0.48 0.66 0.57
HG -0.77 1.00 0.69 0.74 0.61 0.61 0.58
RM 0.62 0.69 1.00 0.75 0.48 0.64 0.68
SJ 0.71 0.74 0.75 1.00 0.50 0.70 0.65
XB 0.48 0.61 0.48 0.50 1.00 -0.46 0.51
XN 0.66 0.61 0.64 0.70 -0.46 1.00 0.75
ZG 0.57 0.58 0.68 0.65 0.51 0.75 1.00
我拿了Stefan的数据,稍微修改了一下。让我们假设这是一个相关矩阵。现在要创建相关图表,您可以简单地这样做:
In [7]: c = corrplot.Corrplot(corr)
...: c.plot()
Correlation chart with ellipses
您可以阅读更多示例here。