Python可视化图表——绘制小提琴图

用Python绘制小提琴图主要用到violinplot这个函数,函数的API是

sns.violinplot(x=None, y=None, hue=None, data=None, order=None, hue_order=None, bw='scott', cut=2, scale='area', scale_hue=True, gridsize=100, width=0.8, inner='box', split=False, dodge=True, orient=None, linewidth=None, color=None, palette=None, saturation=0.75, ax=None, **kwargs)

参数:

x 和 y:分别指定数据的 x 轴和 y 轴。x 通常用于指定类别或分组数据,y 通常用于指定数值数据。

data:一个 DataFrame,用于指定数据集,可以在其中指定 x 和 y 列名,而不必显式传递 x 和 y。

hue:一个列名或变量,用于根据其值对数据进行分组,生成不同颜色的小提琴。

order 和 hue_order:指定 x 轴或 hue 中类别的显示顺序。

bw:控制小提琴图的带宽(它影响小提琴的平滑度,值越小越平滑,越大越粗糙)。

scale:控制小提琴图的宽度。可以设置为 "area"(面积相等,默认值)、"count"(按照样本数量标准化)、"width"(固定宽度)。

inner:设置小提琴内部图形的类型,可以是 "box"、"quart"、"point"、"stick" 或 None。默认为 "box"。

split:当使用 hue 参数进行分组时,设置为 True 时,将小提琴图拆分成两半,分别表示不同的 hue 类别。

palette:指定颜色调色板,用于不同类别的颜色着色。

showmedians:设置为 True 时,显示小提琴中位数的点。

showextrema:设置为 True 时,显示小提琴顶端和底端的线段。

showcaps:设置为 True 时,显示小提琴图的顶部和底部的线段。

inner_kwargs:一个字典,用于传递给内部图形绘制函数的其他参数。

代码:

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

# 创建一个示例DataFrame
data = {
    "Category": ["A", "B", "A", "C", "B", "A", "C", "A", "B", "C"],
    "Value": [5.1, 4.9, 5.5, 6.2, 5.7, 4.8, 6.5, 5.3, 6.0, 6.4]
}

df = pd.DataFrame(data)

# 绘制小提琴图
sns.violinplot(x=df["Category"], y=df["Value"])

# 显示图形
plt.show()

代码: 

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

# 设置绘图风格和背景
sns.set(style="darkgrid")
# 创建一个示例DataFrame
data = {
    "sepal_length": [5.1, 5.9, 6.9, 4.6, 6.0, 6.1, 5.6, 5.4, 6.2, 4.8],
}

df = pd.DataFrame(data)

# Make boxplot for one group only
sns.violinplot(y=df["sepal_length"])
plt.show()

代码

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

sns.set(style="darkgrid")
# 创建一个示例DataFrame
data = {
    "Category": ["A", "B", "A", "C", "B", "A", "C", "A", "B", "C"],
    "Value": [5.1, 4.9, 5.5, 6.2, 5.7, 4.8, 6.5, 5.3, 6.0, 6.4]
}

df = pd.DataFrame(data)

sns.violinplot(y=df["Category"], x=df["Value"])

plt.show()

代码:

import numpy as np
import matplotlib.pyplot as plt
import scipy.stats as st
import pandas as pd

# 加载您的CSV文件
your_data = pd.read_csv('violin_data.csv')  # 替换 'violin_data.csv' 为您的数据文件路径

# 获取类别名称
classes = sorted(your_data["classes"].unique())  # 将代码中的"classes"更改为您的列名 "classes"

# 准备数据
y_data = [your_data[your_data["classes"] == c]["values"].values for c in classes]  # 更改列名

jitter = 0.04
x_data = [np.array([i] * len(d)) for i, d in enumerate(y_data)]
x_jittered = [x + st.t(df=6, scale=jitter).rvs(len(x)) for x in x_data]

# 设置颜色
BG_WHITE = "#fbf9f4"
GREY_LIGHT = "#b4aea9"
GREY50 = "#7F7F7F"
BLUE_DARK = "#1B2838"
BLUE = "#2a475e"
BLACK = "#282724"
GREY_DARK = "#747473"
RED_DARK = "#850e00"
COLOR_SCALE = ["#1B9E77", "#D95F02", "#7570B3"]
POSITIONS = [0, 1, 2]
HLINES = [40, 50, 60]

# 创建图形和坐标轴对象
fig, ax = plt.subplots(figsize=(14, 10))

# 设置布局 ----------------------------------------------
# 背景颜色
fig.patch.set_facecolor(BG_WHITE)
ax.set_facecolor(BG_WHITE)

# 用于作为比例参考的水平线
for h in HLINES:
    ax.axhline(h, color=GREY50, ls=(0, (5, 5)), alpha=0.8, zorder=0)

# 添加小提琴图 ----------------------------------------------------
# bw_method="silverman" 表示核密度估计的带宽使用Silverman法则计算

# 输出存储在 'violins' 中,用于自定义它们的外观
violins = ax.violinplot(
    y_data,
    positions=POSITIONS,
    widths=0.45,
    bw_method="silverman",
    showmeans=False,
    showmedians=False,
    showextrema=False
)

# 自定义小提琴图 (移除填充,自定义线条等)
for pc in violins["bodies"]:
    pc.set_facecolor("none")
    pc.set_edgecolor(BLACK)
    pc.set_linewidth(1.4)
    pc.set_alpha(1)

# 添加箱线图 ---------------------------------------------------
# 注意,关于中位数和箱子的属性以字典形式传递。

medianprops = dict(
    linewidth=4,
    color=GREY_DARK,
    solid_capstyle="butt"
)
boxprops = dict(
    linewidth=2,
    color=GREY_DARK
)

ax.boxplot(
    y_data,
    positions=POSITIONS,
    showfliers=False,  # 不显示超出箱顶和箱底的异常值
    showcaps=False,  # 不显示箱顶和箱底
    medianprops=medianprops,
    whiskerprops=boxprops,
    boxprops=boxprops
)

# 添加 jittered 点 ----------------------------------------------
for x, y, color in zip(x_jittered, y_data, COLOR_SCALE):
    ax.scatter(x, y, s=100, color=color, alpha=0.4)

# 添加均值标签  ------------------------------------------
means = [y.mean() for y in y_data]
for i, mean in enumerate(means):
    # 添加表示均值的点
    ax.scatter(i, mean, s=250, color=RED_DARK, zorder=3)

    # 添加连接均值和标签的线
    ax.plot([i, i + 0.25], [mean, mean], ls="dashdot", color="black", zorder=3)

    # 添加均值标签
    ax.text(
        i + 0.25,
        mean,
        r"$\hat{\mu}_{\rm{mean}} = $" + str(round(mean, 2)),
        fontsize=13,
        va="center",
        bbox=dict(
            facecolor="white",
            edgecolor="black",
            boxstyle="round",
            pad=0.15
        ),
        zorder=10  # 确保线在顶部
    )

# 自定义布局 -----------------------------------------------
# 隐藏轴线
ax.spines["right"].set_color("none")
ax.spines["top"].set_color("none")

# 自定义轴线颜色
ax.spines["left"].set_color(GREY_LIGHT)
ax.spines["left"].set_linewidth(2)
ax.spines["bottom"].set_color(GREY_LIGHT)
ax.spines["bottom"].set_linewidth(2)

# 自定义标签和刻度
ax.tick_params(length=0)
ax.set_yticks(HLINES)
ax.set_yticklabels(HLINES, size=15)
ax.set_ylabel("data", size=18, weight="bold")

# x轴标签包括每个物种的样本大小
xlabels = [f"{classes}\n(n={y_data[i].size})" for i, classes in enumerate(classes)]
ax.set_xticks(POSITIONS)
ax.set_xticklabels(xlabels, size=15, ha="center", ma="center")
ax.set_xlabel("class", size=18, weight="bold")

# 标题
fig.suptitle(
    "Title",
    x = 0.5,
    y = 0.975,
    ha="center",
    fontsize=26,
    fontname="Lobster Two",
    color=BLUE,
    weight="bold",
)


# 显示图形
plt.show()

  • 4
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

咸鱼翻身的路上

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值