Seaborn 小提琴图不与 x 轴标签对齐

Seaborn violin plots don't align with x-axis labels

我正在尝试构建一个小提琴图来说明 y 轴上的深度和与 x 轴上已知点的距离。我能够让 x 轴标签根据可变距离在 x 轴上适当地分布,但我无法让小提琴图对齐。他们的情节似乎转移到 y 轴。任何帮助,将不胜感激。我的代码如下:

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import seaborn as sns

path = 'O:\info1.csv'
df = pd.read_csv(path)
item = ['a', 'b', 'c', 'd', 'e', 'f']
dist = [450, 1400, 2620, 3100, 3830, 4940]

plt.rcParams.update({'font.size': 15})
fig, axes1 = plt.subplots(figsize=(20,10))

axes1 = sns.violinplot(x='item', y='surface', data=df, hue = 'item', order = (item))

axes1.invert_yaxis()
axes1.set_xlabel('Item')
axes1.set_ylabel('Depth')
axes1.set_xticks(dist)
plt.xticks(rotation=20)

plt.show()

示例数据集:

感谢您提供一些数据。 要更改绘图,需要调整代码中的 itemdist 变量,并删除代码中的 item = [a,b...]dist = [] 数组。使用 axes1.set_xticks 的 x 轴上的刻度需要进行一些调整才能获得您想要的内容。

示例 1: 删除了创建您之前看到的绘图的两个数组; violinplot 函数未更改。

# item = ['a', 'b', 'c', 'd', 'e', 'f'] * Removed
# dist = [450, 1400, 2620, 3100, 3830, 4940] * Removed

plt.rcParams.update({'font.size': 15})
fig, axes1 = plt.subplots(figsize=(20,10))

axes1 = sb.violinplot(x='item', y='surface', data=df, hue = 'item', inner = 'box')

axes1.invert_yaxis()
axes1.set_xlabel('Item')
axes1.set_ylabel('Depth')
#axes1.set_xticks(dist) * Removed
plt.xticks(rotation=20)

plt.show()

在每条曲线的内部,都有一个黑色的形状,里面有一个白点。这就是上面提到的微型箱线图。如果您想删除箱形图,可以在 violinplot 调用中设置 inner = None 参数以简化最终可视化的外观。

示例 2: dist 放在 x 轴上代替 xticks

plt.rcParams.update({'font.size': 15})
plt.subplots(figsize=(20,10))
# Put 'dist' as your x input, keep your categorical variable (hue) equal to 'item'
axes1 = sb.violinplot(data = df, x = 'dist', y = 'surface', hue = 'item', inner = 'box');
axes1.invert_yaxis()
axes1.set_xlabel('Item')
axes1.set_ylabel('Depth');

我不确定您正在处理的项目和距离是否具有您想要在 x 轴上显示的关系,或者您是否只想使用这些整数作为该轴的刻度线。如果 itemdist 之间有重要关系,你可以使用字典 new_dict = {450: 'a', 1400: 'b', 2620: 'c' ...

希望这对您有所帮助。

你不能使用 seaborn 小提琴情节,因为从小插图:

This function always treats one of the variables as categorical and draws data at ordinal positions (0, 1, … n) on the relevant axis, even when the data has a numeric or date type.

所以如果直接用seaborn绘制的话,就是categorical:

sns.violinplot(x='dist', y='surface', data=df, hue = 'item',dodge=False,cut=0)

要根据需要放置箱线图,您需要使用 matplotlib,首先我们以所需的格式获取数据并定义调色板:

surface_values = list([np.array(value) for name,value in df.groupby('item')['surface']])
dist_values = df.groupby('item')['dist'].agg("mean")
pal = ["crimson","darkblue","rebeccapurple"]

需要设置宽度,提供距离,对于内"box",我们修改代码从here:

fig, ax = plt.subplots(1, 1,figsize=(8,4))

parts = ax.violinplot(surface_values,widths=200,positions=dist_values,
              showmeans=False, showmedians=False,showextrema=False)

for i,pc in enumerate(parts['bodies']):
    pc.set_facecolor(pal[i])
    pc.set_edgecolor('black')
    pc.set_alpha(1)

quartile1, medians, quartile3 = np.percentile(surface_values, [25, 50, 75], axis=1)
whiskers = np.array([
    adjacent_values(sorted_array, q1, q3)
    for sorted_array, q1, q3 in zip(surface_values, quartile1, quartile3)])
whiskersMin, whiskersMax = whiskers[:, 0], whiskers[:, 1]

inds = dist_values
ax.scatter(inds, medians, marker='o', color='white', s=30, zorder=3)
ax.vlines(inds, quartile1, quartile3, color='k', linestyle='-', lw=5)
ax.vlines(inds, whiskersMin, whiskersMax, color='k', linestyle='-', lw=1)

如果不需要内盒,直接调用plt.violin ...