对数尺度的 Seaborn 条带图
Seaborn stripplot in logscale
我正在使用 pyplot.boxplots 在 logscale 中绘制箱线图,然后我想使用 seaborn 在它上面做 swarmplot/strip 绘图。
然而,seaborn 把我们的整个规模搞得一团糟,而且情节非常荒谬。知道如何在 seaborn 中提供自定义位置吗?
att1= np.sort(np.unique(df1.att1))
w = 0.085
width = lambda p, w: 10 ** (np.log10(p) + w / 2.) - 10 ** (np.log10(p) - w / 2.)
custom_widths = width(freqns, w)
ax.boxplot([df1[df1.att1== xi].att2 for xi in att1], positions=att1,
boxprops={'facecolor': 'none'}, medianprops={'color': 'black'}, patch_artist=True,
widths=custom_widths)
ax.set_xscale("log")
fig.set_size_inches(10.5, 8)
means = [np.median(df1[df1.Frequency == xi].CapDensity) for xi in freqs]
plt.plot(freqns, means, '--k*', lw=1.2)
这是图像w/o带状图:
sns.stripplot(x="Frequency", y="CapDensity",data=df1, edgecolor="black", linewidth=.3, jitter=0.1, zorder=0.5, ax=ax)
这是我在箱线图上绘制带状图的时候。
问题是您使用 att1
作为箱线图的位置,而 seaborn 总是将条带图放在内部位置 0,1,2,3,...
。最简单的解决方案是也通过 matplotlib 创建 stripplot。 (创建群图要复杂得多。)
假设您有与上一个问题相似的数据,这样的图可以创建为:
from matplotlib import pyplot as plt
import numpy as np
import pandas as pd
df = pd.DataFrame({'x': np.random.choice([1, 3, 5, 8, 10, 30, 50, 100], 500),
'y': np.random.normal(750, 20, 500)})
xvals = np.unique(df.x)
w = 0.085
width = lambda p, w: 10 ** (np.log10(p) + w / 2.) - 10 ** (np.log10(p) - w / 2.)
custom_widths = width(xvals, w)
fig, ax = plt.subplots(figsize=(12, 4))
ax.set_xscale('log')
ax.boxplot([df[df.x == xi].y for xi in xvals],
positions=xvals, showfliers=False,
boxprops={'facecolor': 'none'}, medianprops={'color': 'black'}, patch_artist=True,
widths=custom_widths)
medians = [np.median(df[df.x == xi].y) for xi in xvals]
ax.plot(xvals, medians, '--k*', lw=2)
ax.set_xticks(xvals)
for xi, wi in zip(xvals, custom_widths):
yis = df[df.x == xi].y
ax.scatter(xi + np.random.uniform(-wi / 2, wi / 2, yis.size), yis)
plt.show()
我正在使用 pyplot.boxplots 在 logscale 中绘制箱线图,然后我想使用 seaborn 在它上面做 swarmplot/strip 绘图。 然而,seaborn 把我们的整个规模搞得一团糟,而且情节非常荒谬。知道如何在 seaborn 中提供自定义位置吗?
att1= np.sort(np.unique(df1.att1))
w = 0.085
width = lambda p, w: 10 ** (np.log10(p) + w / 2.) - 10 ** (np.log10(p) - w / 2.)
custom_widths = width(freqns, w)
ax.boxplot([df1[df1.att1== xi].att2 for xi in att1], positions=att1,
boxprops={'facecolor': 'none'}, medianprops={'color': 'black'}, patch_artist=True,
widths=custom_widths)
ax.set_xscale("log")
fig.set_size_inches(10.5, 8)
means = [np.median(df1[df1.Frequency == xi].CapDensity) for xi in freqs]
plt.plot(freqns, means, '--k*', lw=1.2)
这是图像w/o带状图:
sns.stripplot(x="Frequency", y="CapDensity",data=df1, edgecolor="black", linewidth=.3, jitter=0.1, zorder=0.5, ax=ax)
这是我在箱线图上绘制带状图的时候。
问题是您使用 att1
作为箱线图的位置,而 seaborn 总是将条带图放在内部位置 0,1,2,3,...
。最简单的解决方案是也通过 matplotlib 创建 stripplot。 (创建群图要复杂得多。)
假设您有与上一个问题相似的数据,这样的图可以创建为:
from matplotlib import pyplot as plt
import numpy as np
import pandas as pd
df = pd.DataFrame({'x': np.random.choice([1, 3, 5, 8, 10, 30, 50, 100], 500),
'y': np.random.normal(750, 20, 500)})
xvals = np.unique(df.x)
w = 0.085
width = lambda p, w: 10 ** (np.log10(p) + w / 2.) - 10 ** (np.log10(p) - w / 2.)
custom_widths = width(xvals, w)
fig, ax = plt.subplots(figsize=(12, 4))
ax.set_xscale('log')
ax.boxplot([df[df.x == xi].y for xi in xvals],
positions=xvals, showfliers=False,
boxprops={'facecolor': 'none'}, medianprops={'color': 'black'}, patch_artist=True,
widths=custom_widths)
medians = [np.median(df[df.x == xi].y) for xi in xvals]
ax.plot(xvals, medians, '--k*', lw=2)
ax.set_xticks(xvals)
for xi, wi in zip(xvals, custom_widths):
yis = df[df.x == xi].y
ax.scatter(xi + np.random.uniform(-wi / 2, wi / 2, yis.size), yis)
plt.show()