使用 Seaborn 在散点图上绘制线条
Drawing lines on scatter with Seaborn
我的 objective 是在使用 seaborn 绘制的图上的 y = 0 上绘制一条水平红线:sns.lmplot
由 col=
或 row=
拆分。
import numpy as np, seaborn as sns, pandas as pd
np.random.seed(5)
myData = pd.DataFrame({'x' : np.arange(1, 101), 'y': np.random.normal(0, 4, 100),\
'z' : ['a','b']*50, 'w':np.random.poisson(0.15,100)})
sns.lmplot("x", "y", col="z", row="w", data=myData, fit_reg=False)
plt.plot(np.linspace(-20,120,1000), [0]*1000, 'r-')
我们可以看到只有最后一个图,在图的数组中,用红线标记:
感谢您的帮助,
编辑: 改写了问题以说明我们使用 col=
and/or row=
生成图表数组的情况,我们希望在每个地块上追踪线条。
Seaborn 实际上只是 matplotlib 的一个接口,因此您也可以使用所有标准的 matplotlib 函数。在你的 seaborn 绘图对我有用后导入 pyplot 并绘制一条红色水平线。
import numpy as np, seaborn as sns, pandas as pd
import matplotlib.pyplt as plt
np.random.seed(5)
myData = pd.DataFrame({'x' : np.arange(1, 101), 'y': np.random.normal(0, 4, 100)})
sns.lmplot("x", "y", data=myData, line_kws={'xdata': '0,1','ydata': '0,0','color': 'k', 'linestyle':'-', 'linewidth':'5'}, fit_reg=False)
plt.plot(np.linspace(-20,120,1000), [0]*1000, 'r')
我的头像在这里 - http://i.imgur.com/J7Lvt52.png
因此这段代码适用于我们使用 col=
、row=
和 hue=
.
的一般情况
import numpy as np, seaborn as sns, pandas as pd
np.random.seed(5)
myData = pd.DataFrame({'x' : np.arange(1, 101), 'y': np.random.normal(0, 4, 100),\
'z' : ['a','b']*50, 'w':np.random.poisson(0.15,100), 'hueMe':['q','w','e','r','t']*20})
myPlot = sns.FacetGrid(col="z", row='w', hue='hueMe', data=myData, size=5)
myPlot = myPlot.map(plt.scatter, "x", "y").set(xlim=(-20,120) , ylim=(-15,15))
myPlot = myPlot.map_dataframe(plt.plot, [-20,120], [0,0], 'r-').add_legend().set_axis_labels("x", "y")
plt.show()
不确定为什么水平线的颜色是每个单独图上使用的最后一种颜色,但我暂时放弃了:)
自从我在寻找答案时遇到这个问题,这里是我最终发现的一个更通用的答案:
map_dataframe
还将接受用户定义的函数(并将数据框传递给此函数),该函数非常强大,因为您可以在 facetgrid 上绘制任何内容。在 OP 案例中:
def plot_hline(y,**kwargs):
data = kwargs.pop("data") #get the data frame from the kwargs
plt.axhline(y=y, c='red',linestyle='dashed',zorder=-1) #zorder places the line underneath the other points
myPlot = sns.FacetGrid(col="z", row='w', hue='hueMe', data=myData, size=5)
myPlot.map(plt.scatter, "x", "y").set(xlim=(-20,120) , ylim=(-15,15))
myPlot.map_dataframe(plot_hline,y=0)
plt.show()
我的问题稍微复杂一些,因为我想在每个面都有不同的水平线。
为了复制我的案例,假设 'z' 变量有两个样本(a 和 b),每个样本都有一个观测值 'obs'(我已将其添加到下面的 myData 中)。 'hueMe' 表示每个样本的建模值。
myData = pd.DataFrame({'x' : np.arange(1, 101),
'y': np.random.normal(0, 4, 100),
'z' : ['a','b']*50,
'w':np.random.poisson(0.15,100),
'hueMe':['q','w','e','r','t']*20,
'obs':[3,2]*50})
当您将数据框传递给plot_hline
时,您需要为每个'z'样本删除'obs'的重复值,因为axhline只能为[=取一个值15=]。 (请记住,在我们的例子中,每个样本都有 1 个观察值 'obs',但有多个建模值 'hueMe')。此外,y
必须是标量(而不是系列),因此您需要索引数据框以提取值本身。
def plot_hline(y,z, **kwargs):
data = kwargs.pop("data") #the data passed in through kwargs is a subset of the original data - only the subset for the row and col being plotted. it's a for loop in disguise.
data = data.drop_duplicates([z]) #drop the duplicate rows
yval = data[y].iloc[0] #extract the value for your hline.
plt.axhline(y=yval, c='red',linestyle='dashed',zorder=-1)
myPlot = sns.FacetGrid(col="z", row='w', hue='hueMe', data=myData, size=5)
myPlot.map(plt.scatter, "x", "y").set(xlim=(-20,120) , ylim=(-15,15))
myPlot.map_dataframe(plot_hline,y='obs',z='z')
plt.show()
resulting plot
现在 seaborn 将函数的输出映射到 FacetGrid
的每个方面。请注意,如果您使用的绘图函数与 axhline 不同,您可能不一定需要从系列中提取值。
希望这对某人有所帮助!
我的 objective 是在使用 seaborn 绘制的图上的 y = 0 上绘制一条水平红线:sns.lmplot
由 col=
或 row=
拆分。
import numpy as np, seaborn as sns, pandas as pd
np.random.seed(5)
myData = pd.DataFrame({'x' : np.arange(1, 101), 'y': np.random.normal(0, 4, 100),\
'z' : ['a','b']*50, 'w':np.random.poisson(0.15,100)})
sns.lmplot("x", "y", col="z", row="w", data=myData, fit_reg=False)
plt.plot(np.linspace(-20,120,1000), [0]*1000, 'r-')
我们可以看到只有最后一个图,在图的数组中,用红线标记:
感谢您的帮助,
编辑: 改写了问题以说明我们使用 col=
and/or row=
生成图表数组的情况,我们希望在每个地块上追踪线条。
Seaborn 实际上只是 matplotlib 的一个接口,因此您也可以使用所有标准的 matplotlib 函数。在你的 seaborn 绘图对我有用后导入 pyplot 并绘制一条红色水平线。
import numpy as np, seaborn as sns, pandas as pd
import matplotlib.pyplt as plt
np.random.seed(5)
myData = pd.DataFrame({'x' : np.arange(1, 101), 'y': np.random.normal(0, 4, 100)})
sns.lmplot("x", "y", data=myData, line_kws={'xdata': '0,1','ydata': '0,0','color': 'k', 'linestyle':'-', 'linewidth':'5'}, fit_reg=False)
plt.plot(np.linspace(-20,120,1000), [0]*1000, 'r')
我的头像在这里 - http://i.imgur.com/J7Lvt52.png
因此这段代码适用于我们使用 col=
、row=
和 hue=
.
import numpy as np, seaborn as sns, pandas as pd
np.random.seed(5)
myData = pd.DataFrame({'x' : np.arange(1, 101), 'y': np.random.normal(0, 4, 100),\
'z' : ['a','b']*50, 'w':np.random.poisson(0.15,100), 'hueMe':['q','w','e','r','t']*20})
myPlot = sns.FacetGrid(col="z", row='w', hue='hueMe', data=myData, size=5)
myPlot = myPlot.map(plt.scatter, "x", "y").set(xlim=(-20,120) , ylim=(-15,15))
myPlot = myPlot.map_dataframe(plt.plot, [-20,120], [0,0], 'r-').add_legend().set_axis_labels("x", "y")
plt.show()
不确定为什么水平线的颜色是每个单独图上使用的最后一种颜色,但我暂时放弃了:)
自从我在寻找答案时遇到这个问题,这里是我最终发现的一个更通用的答案:
map_dataframe
还将接受用户定义的函数(并将数据框传递给此函数),该函数非常强大,因为您可以在 facetgrid 上绘制任何内容。在 OP 案例中:
def plot_hline(y,**kwargs):
data = kwargs.pop("data") #get the data frame from the kwargs
plt.axhline(y=y, c='red',linestyle='dashed',zorder=-1) #zorder places the line underneath the other points
myPlot = sns.FacetGrid(col="z", row='w', hue='hueMe', data=myData, size=5)
myPlot.map(plt.scatter, "x", "y").set(xlim=(-20,120) , ylim=(-15,15))
myPlot.map_dataframe(plot_hline,y=0)
plt.show()
我的问题稍微复杂一些,因为我想在每个面都有不同的水平线。
为了复制我的案例,假设 'z' 变量有两个样本(a 和 b),每个样本都有一个观测值 'obs'(我已将其添加到下面的 myData 中)。 'hueMe' 表示每个样本的建模值。
myData = pd.DataFrame({'x' : np.arange(1, 101),
'y': np.random.normal(0, 4, 100),
'z' : ['a','b']*50,
'w':np.random.poisson(0.15,100),
'hueMe':['q','w','e','r','t']*20,
'obs':[3,2]*50})
当您将数据框传递给plot_hline
时,您需要为每个'z'样本删除'obs'的重复值,因为axhline只能为[=取一个值15=]。 (请记住,在我们的例子中,每个样本都有 1 个观察值 'obs',但有多个建模值 'hueMe')。此外,y
必须是标量(而不是系列),因此您需要索引数据框以提取值本身。
def plot_hline(y,z, **kwargs):
data = kwargs.pop("data") #the data passed in through kwargs is a subset of the original data - only the subset for the row and col being plotted. it's a for loop in disguise.
data = data.drop_duplicates([z]) #drop the duplicate rows
yval = data[y].iloc[0] #extract the value for your hline.
plt.axhline(y=yval, c='red',linestyle='dashed',zorder=-1)
myPlot = sns.FacetGrid(col="z", row='w', hue='hueMe', data=myData, size=5)
myPlot.map(plt.scatter, "x", "y").set(xlim=(-20,120) , ylim=(-15,15))
myPlot.map_dataframe(plot_hline,y='obs',z='z')
plt.show()
resulting plot
现在 seaborn 将函数的输出映射到 FacetGrid
的每个方面。请注意,如果您使用的绘图函数与 axhline 不同,您可能不一定需要从系列中提取值。
希望这对某人有所帮助!