我想根据代表样本大小的 numpy 数组来改变我的 seaborn 点图中的标记大小。
markersize_array = np.array([[10, 5, 6]])
将
markersize_array
提供给 markersize
关键字会产生错误:
TypeError: only length-1 arrays can be converted to Python scalars
这是一些示例代码:
penguins = sns.load_dataset("penguins")
fig, ax = plt.subplots(1, 1, figsize=(2, 2))
markersize_array = np.array([[10, 5, 6]])
sns.pointplot(
data=penguins,
x="body_mass_g",
y="island",
ax=ax,
estimator=np.mean,
errorbar=('ci', 95),
capsize=0,
color="k",
log_scale=False,
linestyle="none",
marker="s",
markersize=np.array([[5]]),
# markersize=markersize_array, # <- I need this
)
有办法做到这一点吗?
使用seaborn对象也不起作用:
import seaborn.objects as so
tips = sns.load_dataset("tips")
p1 = so.Plot(tips, "total_bill", "tip")
p1.add(so.Dot())
(
so.Plot(tips, x="total_bill", y="day")
.add(so.Dot(pointsize=np.array(10)), so.Agg())
# .add(so.Dot(pointsize=np.array([[10, 10, 10, 10]])), so.Agg())
.add(so.Range(), so.Est(errorbar=("se", 2)))
)
ChatGPT 为我提供了一种使用 matplotlib 的解决方法,该方法需要很多行代码但达到了预期的结果:
import seaborn as sns
import matplotlib.pyplot as plt
import numpy as np
import scipy.stats as stats
# Load the example dataset
penguins = sns.load_dataset("penguins")
# Example data to simulate markersize array
markersize_array = np.array([10, 5, 6])
# Calculate the means and sample sizes
grouped_data = penguins.groupby("island")["body_mass_g"].agg(["mean", "count"])
ci_bounds = penguins.groupby("island")["body_mass_g"].apply(
lambda x: sns.utils.ci(sns.algorithms.bootstrap(x, func=np.mean), 95)
)
# Create the plot
fig, ax = plt.subplots(figsize=(5, 5))
# Iterate through the islands and plot each point individually with the corresponding marker size
for i, island in enumerate(grouped_data.index):
# Extract the mean, CI lower, and upper bounds
mean_val = grouped_data.loc[island, "mean"]
ci_lower, ci_upper = ci_bounds[island]
# Plot the point
ax.errorbar(
mean_val, # x value (mean)
island, # y value (island)
xerr=[[mean_val - ci_lower], [ci_upper - mean_val]], # CI as error bars
fmt='o', # marker style
color='k', # color of the point
markersize=markersize_array[i], # marker size from array
capsize=5, # size of the caps on the error bars
)
# Final plot adjustments
ax.set_xlabel("Body Mass (g)")
ax.set_title("Body Mass by Island with Varying Marker Sizes")
sns.despine()
plt.tight_layout()
plt.show()