如何在 ECDF 图上使用标记
How to use markers with ECDF plot
为了获得带有seaborn的ECDF地块,应执行以下操作:
sns.ecdfplot(data=myData, x='x', ax=axs, hue='mySeries')
这将为 myData
内的每个系列 mySeries
提供 ECDF 图。
现在,我想为每个系列都使用标记。我尝试使用与 sns.lineplot
示例相同的逻辑,如下所示:
sns.lineplot(data=myData,x='x',y='y',ax=axs,hue='mySeries',markers=True, style='mySeries',)
但是,不幸的是,关键字 markers
或 style
不适用于 sns.ecdf
图。我正在使用 seaborn 0.11.2.
对于可重现的示例,可以使用企鹅数据集:
import seaborn as sns
penguins = sns.load_dataset('penguins')
sns.ecdfplot(data=penguins, x="bill_length_mm", hue="species")
您可以遍历生成的行并应用标记。这是一个使用企鹅数据集的示例,一次使用默认设置,然后使用标记,第三次使用不同的线型:
import matplotlib.pyplot as plt
import seaborn as sns
penguins = sns.load_dataset('penguins')
fig, (ax1, ax2, ax3) = plt.subplots(ncols=3, figsize=(15, 4))
sns.ecdfplot(data=penguins, x="bill_length_mm", hue="species", ax=ax1)
ax1.set_title('Default')
sns.ecdfplot(data=penguins, x="bill_length_mm", hue="species", ax=ax2)
for lines, marker, legend_handle in zip(ax2.lines[::-1], ['*', 'o', '+'], ax2.legend_.legendHandles):
lines.set_marker(marker)
legend_handle.set_marker(marker)
ax2.set_title('Using markers')
sns.ecdfplot(data=penguins, x="bill_length_mm", hue="species", ax=ax3)
for lines, linestyle, legend_handle in zip(ax3.lines[::-1], ['-', '--', ':'], ax3.legend_.legendHandles):
lines.set_linestyle(linestyle)
legend_handle.set_linestyle(linestyle)
ax3.set_title('Using linestyles')
plt.tight_layout()
plt.show()
- 如
seaborn.ecdfplot
, other keyword arguments are passed to matplotlib.axes.Axes.plot()
, which accepts marker
and linestyle / ls
的文档中所述
marker
和 ls
接受单个字符串,该字符串适用于绘图中的所有 hue
组。
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
df = sns.load_dataset('penguins', cache=True)
sns.ecdfplot(data=df, x="culmen_length_mm", hue="species", marker='^', ls='none', palette='colorblind')
直接计算ECDF
- 允许使用
seaborn.lineplot
or matplotlib.pyplot.plot
的选项是直接计算 ECDF 的 x
和 y
。
- Plotting all of your data: Empirical cumulative distribution functions
def ecdf(data, array: bool=True):
"""Compute ECDF for a one-dimensional array of measurements."""
# Number of data points: n
n = len(data)
# x-data for the ECDF: x
x = np.sort(data)
# y-data for the ECDF: y
y = np.arange(1, n+1) / n
if not array:
return pd.DataFrame({'x': x, 'y': y})
else:
return x, y
matplotlib.pyplot.plot
x, y = ecdf(df.culmen_length_mm)
plt.plot(x, y, marker='.', linestyle='none', color='tab:blue')
plt.title('All Species')
plt.xlabel('Culmen Length (mm)')
plt.ylabel('ECDF')
plt.margins(0.02) # keep data off plot edges
- 对于多个组,如 JohanC
所建议
for species, marker in zip(df['species'].unique(), ['*', 'o', '+']):
x, y = ecdf(df[df['species'] == species].culmen_length_mm)
plt.plot(x, y, marker=marker, linestyle='none', label=species)
plt.legend(title='Species', bbox_to_anchor=(1, 1.02), loc='upper left')
seaborn.lineplot
# groupy to get the ecdf for each species
dfg = df.groupby('species')['culmen_length_mm'].apply(ecdf, False).reset_index(level=0).reset_index(drop=True)
# plot
p = sns.lineplot(data=dfg, x='x', y='y', hue='species', style='species', markers=True, palette='colorblind')
sns.move_legend(p, bbox_to_anchor=(1, 1.02), loc='upper left')
为了获得带有seaborn的ECDF地块,应执行以下操作:
sns.ecdfplot(data=myData, x='x', ax=axs, hue='mySeries')
这将为 myData
内的每个系列 mySeries
提供 ECDF 图。
现在,我想为每个系列都使用标记。我尝试使用与 sns.lineplot
示例相同的逻辑,如下所示:
sns.lineplot(data=myData,x='x',y='y',ax=axs,hue='mySeries',markers=True, style='mySeries',)
但是,不幸的是,关键字 markers
或 style
不适用于 sns.ecdf
图。我正在使用 seaborn 0.11.2.
对于可重现的示例,可以使用企鹅数据集:
import seaborn as sns
penguins = sns.load_dataset('penguins')
sns.ecdfplot(data=penguins, x="bill_length_mm", hue="species")
您可以遍历生成的行并应用标记。这是一个使用企鹅数据集的示例,一次使用默认设置,然后使用标记,第三次使用不同的线型:
import matplotlib.pyplot as plt
import seaborn as sns
penguins = sns.load_dataset('penguins')
fig, (ax1, ax2, ax3) = plt.subplots(ncols=3, figsize=(15, 4))
sns.ecdfplot(data=penguins, x="bill_length_mm", hue="species", ax=ax1)
ax1.set_title('Default')
sns.ecdfplot(data=penguins, x="bill_length_mm", hue="species", ax=ax2)
for lines, marker, legend_handle in zip(ax2.lines[::-1], ['*', 'o', '+'], ax2.legend_.legendHandles):
lines.set_marker(marker)
legend_handle.set_marker(marker)
ax2.set_title('Using markers')
sns.ecdfplot(data=penguins, x="bill_length_mm", hue="species", ax=ax3)
for lines, linestyle, legend_handle in zip(ax3.lines[::-1], ['-', '--', ':'], ax3.legend_.legendHandles):
lines.set_linestyle(linestyle)
legend_handle.set_linestyle(linestyle)
ax3.set_title('Using linestyles')
plt.tight_layout()
plt.show()
- 如
seaborn.ecdfplot
, other keyword arguments are passed tomatplotlib.axes.Axes.plot()
, which acceptsmarker
andlinestyle / ls
的文档中所述marker
和ls
接受单个字符串,该字符串适用于绘图中的所有hue
组。
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
df = sns.load_dataset('penguins', cache=True)
sns.ecdfplot(data=df, x="culmen_length_mm", hue="species", marker='^', ls='none', palette='colorblind')
直接计算ECDF
- 允许使用
seaborn.lineplot
ormatplotlib.pyplot.plot
的选项是直接计算 ECDF 的x
和y
。 - Plotting all of your data: Empirical cumulative distribution functions
def ecdf(data, array: bool=True):
"""Compute ECDF for a one-dimensional array of measurements."""
# Number of data points: n
n = len(data)
# x-data for the ECDF: x
x = np.sort(data)
# y-data for the ECDF: y
y = np.arange(1, n+1) / n
if not array:
return pd.DataFrame({'x': x, 'y': y})
else:
return x, y
matplotlib.pyplot.plot
x, y = ecdf(df.culmen_length_mm)
plt.plot(x, y, marker='.', linestyle='none', color='tab:blue')
plt.title('All Species')
plt.xlabel('Culmen Length (mm)')
plt.ylabel('ECDF')
plt.margins(0.02) # keep data off plot edges
- 对于多个组,如 JohanC 所建议
for species, marker in zip(df['species'].unique(), ['*', 'o', '+']):
x, y = ecdf(df[df['species'] == species].culmen_length_mm)
plt.plot(x, y, marker=marker, linestyle='none', label=species)
plt.legend(title='Species', bbox_to_anchor=(1, 1.02), loc='upper left')
seaborn.lineplot
# groupy to get the ecdf for each species
dfg = df.groupby('species')['culmen_length_mm'].apply(ecdf, False).reset_index(level=0).reset_index(drop=True)
# plot
p = sns.lineplot(data=dfg, x='x', y='y', hue='species', style='species', markers=True, palette='colorblind')
sns.move_legend(p, bbox_to_anchor=(1, 1.02), loc='upper left')