Python数据可视化科技图表绘制系列教程(七)

发布于:2025-09-11 ⋅ 阅读:(15) ⋅ 点赞:(0)

目录

1 三维散点图

2 三维瀑布图

3 三维热图

4 云雨图

5 单类别散点矩阵图

6 环形热图

7 直方热图

8 相关性热图

9 边际直方图


1 三维散点图

# 导入必要的库
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.colors as mcolors

# 尝试读取Excel数据
data = pd.read_excel(r'E:\PythonProjects\experiments_figures\experiments_figures\三维散点图\data.xlsx',
                     engine='openpyxl',
                     sheet_name='Sheet1',
                     header=0)

# 定义投影颜色-映射
color = ['#00ced1', '#cc9900', '#b177de']

# 创建自定义颜色映射-颜色棒
hex_colors = ["#1e3cff", "#d631ff"]#蓝紫色

# 提取X、Y、Z坐标数据
xs = data.iloc[:, 0].values  # 第一列作为X坐标
ys = data.iloc[:, 1].values  # 第二列作为Y坐标
zs = data.iloc[:, 2].values  # 第三列作为Z坐标

# 确保ns是数值类型
ns = pd.to_numeric(data.iloc[:, 3], errors='coerce').values  # 第四列用于散点的大小

# 检查是否有转换失败的值(NaN),如果有则替换为0或其他合适的默认值
if np.isnan(ns).any():
    print("警告:第四列中有非数值数据,已替换为默认值0")
    ns = np.nan_to_num(ns, nan=0.0)

# 计算每个特征的最大最小值
x_min, x_max = np.min(xs), np.max(xs)
y_min, y_max = np.min(ys), np.max(ys)
z_min, z_max = np.min(zs), np.max(zs)
n_min, n_max = np.min(ns), np.max(ns) if np.min(ns) != np.max(ns) else (np.min(ns), np.min(ns) + 1)

# 计算每个坐标轴的偏移量
offset_x = (x_max + x_min) / 2
offset_y = (y_max + y_min) / 2
offset_z = (z_max + z_min) / 2

# 计算坐标轴范围
x_lower = x_min - offset_x
x_upper = x_max + offset_x
y_lower = y_min - offset_y
y_upper = y_max + offset_y
z_lower = z_min - offset_z
z_upper = z_max + offset_z

# 创建3D图形对象
fig = plt.figure(figsize=(10, 8))
ax = fig.add_subplot(111, projection='3d')

# 创建自定义颜色映射
custom_cmap = mcolors.LinearSegmentedColormap.from_list("custom", hex_colors)

# 标准化z值以适应颜色映射
norm = mcolors.Normalize(vmin=z_min, vmax=z_max)

# 使用ns值计算球体大小 - 将ns值映射到合理的球体大小范围
if n_min == n_max:
    sphere_sizes = np.full(len(ns), 0.05)  # 如果所有值相同,使用默认大小
else:
    # 将ns值标准化到0.02-0.1范围(球体半径)
    sphere_sizes = 0.04 + ((ns - n_min) / (n_max - n_min)) * 0.14

# 定义球面网格
u = np.linspace(0, 2 * np.pi, 500)
v = np.linspace(0, np.pi, 500)
x_sphere = np.outer(np.cos(u), np.sin(v))
y_sphere = np.outer(np.sin(u), np.sin(v))
z_sphere = np.outer(np.ones(np.size(u)), np.cos(v))

# 为每个点绘制球体
for i in range(len(xs)):
    # 获取当前点的颜色
    color_val = custom_cmap(norm(zs[i]))

    # 计算球体缩放
    x_scale = sphere_sizes[i] * (x_max - x_min) / 2
    y_scale = sphere_sizes[i] * (y_max - y_min) / 2
    z_scale = sphere_sizes[i] * (z_max - z_min) / 2

    # 绘制球体
    ax.plot_surface(
        xs[i] + x_scale * x_sphere,
        ys[i] + y_scale * y_sphere,
        zs[i] + z_scale * z_sphere,
        color=color_val,
        alpha=1,
        shade=True,
        zorder=10000
    )

# 添加三个平面的投影
# XY平面投影 (z=0)
ax.scatter(xs, ys, np.full(len(xs), z_lower), c=color[0], marker='o', s=20, alpha=0.6, zorder=1)
# XZ平面投影 (y=0)
ax.scatter(xs, np.full(len(ys), y_lower), zs, c=color[1], marker='o', s=20, alpha=0.6, zorder=1)
# YZ平面投影 (x=0)
ax.scatter(np.full(len(zs), x_upper), ys, zs, c=color[2], marker='o', s=20, alpha=0.6, zorder=1)

# 设置刻度个数和标签字体大小
# X轴刻度设置
x_ticks = np.linspace(x_lower, x_upper, 6)  # 设置6个X轴刻度
ax.set_xticks(x_ticks)
# Y轴刻度设置
y_ticks = np.linspace(y_lower, y_upper, 5)  # 设置5个Y轴刻度
ax.set_yticks(y_ticks)
# Z轴刻度设置
z_ticks = np.linspace(z_lower, z_upper, 6)  # 设置6个Z轴刻度
ax.set_zticks(z_ticks)

# 设置所有轴刻度标签的字体大小
ax.tick_params(axis='x', labelsize=12, pad=5)  # X轴刻度标签字体大小
ax.tick_params(axis='y', labelsize=12, pad=7)  # Y轴刻度标签字体大小
ax.tick_params(axis='z', labelsize=12, pad=7)  # Z轴刻度标签字体大小

# 添加颜色条,关键修复:添加ax=ax参数
proxy = plt.cm.ScalarMappable(cmap=custom_cmap, norm=norm)
proxy.set_array(zs)
# 这里添加了ax=ax参数,指定颜色条关联的坐标轴
colbar = fig.colorbar(proxy, ax=ax, shrink=0.5, aspect=10, pad=0.15)
colbar.set_label('Z-value', fontsize=20)  # 设置颜色条标签字体大小
colbar.ax.tick_params(labelsize=12)  # 设置颜色条刻度标签字体大小

# 设置轴标签
ax.set_xlabel('X-axis', fontsize=20, labelpad=25)
ax.set_ylabel('Y-axis', fontsize=20, labelpad=25)
ax.set_zlabel('Z-axis', fontsize=20, labelpad=25)

# 设置标题
ax.set_title('3D scatter diagram', fontsize=24, pad=15)

# 设置坐标轴范围,确保投影点可见
ax.set_xlim(x_lower, x_upper)
ax.set_ylim(y_lower, y_upper)
ax.set_zlim(z_lower, z_upper)

# 调整视角以便更好地查看3D图
ax.view_init(elev=30, azim=135)
# 调整布局,确保所有元素都能正确显示
plt.tight_layout()

# 保存图片(可选)
plt.savefig('三维散点图.png', dpi=600, bbox_inches='tight')
plt.show()
三维散点图

2 三维瀑布图

# 导入必要的库
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib import cm
from mpl_toolkits.mplot3d.art3d import Poly3DCollection

# 从Excel文件读取数据
file_path = r'E:\PythonProjects\experiments_figures\experiments_figures\三维瀑布图\data.xlsx'
data = pd.read_excel(file_path, engine='openpyxl', sheet_name='Sheet1', header=0)

# 定义绘图顺序
drawing_order = ['Group1', 'Group2', 'Group3', 'Group4', 'Group5', 'Group6', 'Group7']

# 使用tab20颜色方案
tab20_colors = cm.tab20(np.linspace(0, 1, len(drawing_order)))
colors = {drawing_order[i]: tuple(tab20_colors[i]) for i in range(len(drawing_order))}

# 获取x值
x_values = data['Count'].values

# 创建图形和3D坐标轴,调整figsize以提供更多空间
fig = plt.figure(figsize=(10, 8))
ax = fig.add_subplot(111, projection='3d')

# 减少子图边距,减小空白
plt.subplots_adjust(left=0.05, right=0.95, bottom=0.05, top=0.9)

# 创建图例补丁列表
legend_patches = []

# 为每个组绘制图形
for i, y_label in enumerate(reversed(drawing_order)):
    color = colors[y_label]
    z_values = data[y_label].values
    x_valid = x_values
    z_valid = z_values

    # 为该组创建y位置
    y_val = drawing_order.index(y_label)
    y_points = np.full_like(x_valid, y_val)

    # 绘制线条和点
    ax.plot(x_valid, y_points, z_valid, color=color, alpha=1, linewidth=1.5)
    ax.scatter(x_valid, y_points, z_valid, color=color, marker='o', s=20)

    # 为奇数编号的点添加标签,增大标签字体
    for x, y, z in zip(x_valid, y_points, z_valid):
        if int(x) % 2 == 1:
            label = f'{z:.1f}' if isinstance(z, float) else str(z)
            ax.text(x, y, z + 0.5, label, ha='center', va='bottom', fontsize=12)

    # 创建3D多边形以实现瀑布效果
    verts = [list(zip(x_valid, y_points, z_valid)),
             list(zip(x_valid, y_points, np.zeros_like(z_valid)))]
    poly = Poly3DCollection([verts[0] + verts[1][::-1]], alpha=0.25)
    poly.set_color(color)
    ax.add_collection3d(poly)

    # 添加到图例
    legend_patches.append(plt.Line2D([0], [0], color=color, lw=2, label=y_label))

# 添加图例,调整位置和字体大小
ax.legend(handles=legend_patches,
          loc='upper left',
          fontsize=12,
          frameon=True,
          shadow=False,
          fancybox=True,
          framealpha=0.8,
          bbox_to_anchor=(1.05, 1))

# 设置标签和标题,增大字体
ax.set_xlabel('Count', fontsize=14, labelpad=10)
ax.set_ylabel('Groups', fontsize=14, labelpad=10)
ax.set_zlabel('Values', fontsize=14, labelpad=10)
ax.set_title('3D Waterfall Chart of Groups', fontdict={'size': 18})

# 设置y轴刻度标签字体大小
ax.set_yticks(range(len(drawing_order)))
ax.set_yticklabels(drawing_order, fontsize=12)

# 调整图表限制以确保所有数据可见
margin = 0.1
x_min, x_max = min(x_values), max(x_values)
y_min, y_max = 0, len(drawing_order) - 1
z_min, z_max = 0, data[drawing_order].values.max() * 1.15

ax.set_xlim(x_min - margin, x_max + margin)
ax.set_ylim(y_min - margin, y_max + margin)
ax.set_zlim(z_min, z_max)

# 优化视角
ax.view_init(elev=35, azim=-45)

# 保存图片为600 DPI的PNG格式
plt.savefig(r'E:\PythonProjects\experiments_figures\experiments_figures\三维瀑布图\三维瀑布图.png',
            dpi=600,
            bbox_inches='tight',
            pad_inches=0.2)

# 显示图表
plt.tight_layout()
plt.show()
三维瀑布图

3 三维热图

# 导入必要的库
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import LinearSegmentedColormap

# 设置中文字体支持(解决中文显示问题)
plt.rcParams["font.family"] = ["SimHei"]  # 使用黑体
plt.rcParams['axes.unicode_minus'] = False  # 解决负号显示为方块的问题

# ================== 数据准备阶段 ==================

# 读取Excel数据 - 使用index_col=0来将第一列设置为索引
data = pd.read_excel(r'E:\PythonProjects\experiments_figures\experiments_figures\三维热图\data.xlsx',
                     engine='openpyxl',
                     sheet_name='Sheet1',
                     index_col=0)  # 这里设置第一列为索引,也就是A到J这些字母

# ================== 数据归一化 ==================

# 提取所有值用于归一化
all_values = data.values.flatten()

# 找出最大值和最小值
min_val = np.min(all_values)
max_val = np.max(all_values)

# 执行Min-Max归一化 (将数据缩放到0-1范围)
normalized_data = (data - min_val) / (max_val - min_val)

# ================== 创建自定义颜色映射 ==================
##1.第一种使用颜色库
# cmap = plt.cm.coolwarm

## 2.定义自定义颜色映射,使用16进制颜色代码
# 从低值到高值的颜色渐变

custom_colors = ["#8e0152", "#c51b7d", "#f1b6da",  # 紫色系
                "#f7f7f7",  # 中性白
                "#e6f5d0", "#b8e186", "#4d9221"]  # 绿色系

# custom_colors = [
#                 "#e5f5f9",  # 浅蓝
#                 "#99d8c9",  # 蓝绿过渡
#                 "#66c2a4",  # 中绿
#                 "#238b45",  # 深绿
#                 "#00441b"   # 墨绿
#                  ]

# custom_colors = ["#FFF5EB",  # 极浅橙 (接近白)
#                 "#FEE6CE",  # 浅奶油橙
#                 "#FDD0A2",  # 淡橙
#                 "#FDAE6B",  # 柔橙
#                 "#FD8D3C",  # 标准浅橙
#                 "#F16913",  # 明亮橙
#                 "#D94801",  # 饱和橙
#                  ]

# custom_colors = [
#                 "#0ebeff",
#                 "#3ea5f0",
#                 "#6e8ce1",
#                 "#9f74d1",
#                 "#cf5bc2",
#                 "#ff42b3",
#                 ]
# custom_colors = [
#                 "#FFC0CB",
#                 "#F3B3C6",
#                 "#E699B3",
#                 "#CC6699",
#                 "#B36666",
#                 "#993366",
#                 ]

#### 创建自定义颜色映射
cmap = LinearSegmentedColormap.from_list('custom_colormap', custom_colors)

# ================== 绘制3D热图 ==================

# 创建一个3D图形
fig = plt.figure(figsize=(12, 10))
ax = fig.add_subplot(111, projection='3d')

# 获取数据维度
rows, cols = data.shape

# 创建x, y坐标网格 - 使用中心坐标
x, y = np.meshgrid(np.arange(cols), np.arange(rows))

# 展平x, y网格和数据矩阵以便绘图
x = x.flatten()
y = y.flatten()
z = np.zeros_like(x)  # 起始高度为0

# 获取归一化后的值作为柱子高度
dz = normalized_data.values.flatten()

# 使用原始数据值的归一化来设置颜色
norm = plt.Normalize(min_val, max_val)
colors = cmap(norm(data.values.flatten()))

# 绘制3D柱状图 - 设置dx和dy相等以确保俯视图为正方形
bar_width = 0.6  # 将宽度设置得更大一些,接近1
ax.bar3d(x, y, z, bar_width, bar_width, dz, shade=True, color=colors, alpha=1)

# 设置x轴和y轴的显示范围,确保正方形布局
ax.set_box_aspect([cols, rows, max(0.7*max(cols, rows), np.max(dz)*1.2)])  # 调整z轴高度比例

# 设置坐标轴标签
ax.set_xlabel('特征', labelpad=10, fontsize=18)
ax.set_ylabel('分组', labelpad=10, fontsize=18)
ax.set_zlabel('归一化数值 (0-1)', labelpad=10, fontsize=18)

# 设置x轴刻度标签为列名,并使其居中对应每个柱子
ax.set_xticks(np.arange(cols) + bar_width/2)
ax.set_xticklabels(data.columns, rotation=45, ha='right', fontsize=18)

# 设置y轴刻度标签为行名,并使其居中对应每个柱子
ax.set_yticks(np.arange(rows) + bar_width/2)
ax.set_yticklabels(data.index, fontsize=18)

# 设置z轴的刻度 - 调整为5个刻度点
z_ticks = np.linspace(0, 1.5, 5)
ax.set_zticks(z_ticks)
ax.set_zticklabels([f"{val:.2f}" for val in z_ticks], fontsize=18)

# 调整视角以便更好地查看3D图
ax.view_init(elev=30, azim=225)

# 添加颜色条以显示原始数值对应的颜色
sm = plt.cm.ScalarMappable(cmap=cmap, norm=norm)
sm.set_array([])
cbar = plt.colorbar(sm, ax=ax, pad=0.1, shrink=0.7, aspect=20)
cbar.set_label('原始数值范围', fontsize=18)
cbar.ax.tick_params(labelsize=18)  # 颜色棒刻度字体大小
# 添加说明
plt.title('三维归一化热图', fontsize=16, pad=20)


# 确保从俯视图看是正方形的
ax.set_proj_type('ortho')  # 使用正交投影

# 调整布局
plt.tight_layout()

# 保存图片(可选)
plt.savefig('三维热图.png', dpi=600, bbox_inches='tight')
plt.show()
三维热图

4 云雨图

# 导入必要的库
import numpy as np  # 数值计算库
import pandas as pd  # 数据处理库
import matplotlib.pyplot as plt  # 绘图库

# ==================== 1. 数据准备 ====================
# 定义Excel文件路径(注意:r表示原始字符串,避免转义字符问题)
file_path = r'E:\PythonProjects\experiments_figures\experiments_figures\云雨图\data.xlsx'
# 使用pandas读取Excel文件
# engine='openpyxl':指定使用openpyxl引擎读取xlsx文件
# sheet_name='Sheet1':读取第一个工作表
# header=0:使用第一行作为列名
df = pd.read_excel(file_path, engine='openpyxl', sheet_name='Sheet1', header=0)

# 数据集的特征变量(列名)
categories = ['A', 'B', 'C', 'D', 'E']

# ==================== 2. 可视化设置 ====================
# 创建图形和坐标轴,设置图形大小为10x8英寸
fig, ax = plt.subplots(figsize=(10, 8))

# 定义颜色方案(颜色个数与变量个数相同)
# 小提琴图颜色(半透明填充) 箱线图颜色(实色填充)
box_colors = violin_colors = ["#d36a87", "#ea9979", "#83b6b5", "#bcdfa7", "#a596ee"]
# box_colors = violin_colors = ['#9bb55e', '#fcd744', '#dc8e4e', '#ba7ab1', '#ea617b']
# 设置类别在x轴上的位置(0,1,2,3,4)
positions = np.arange(len(categories))
box_width = 0.15  # 箱形图宽度
violin_width = 0.5  # 小提琴图宽度

# ==================== 3. 绘制图形 ====================
# 遍历每个类别进行绘图
for i, category in enumerate(categories):
    # 获取当前类别的数据值
    data_points = df[category].values

    # ----------------- 3.1 绘制箱形图 -----------------
    # 箱形图位置向左微调(避免与小提琴图完全重叠)
    box_pos = positions[i] - box_width / 100

    # 绘制箱形图(boxplot)
    box = ax.boxplot(
        data_points,
        positions=[box_pos],  # 指定位置
        widths=box_width,  # 设置宽度
        patch_artist=True,  # 允许填充颜色
        showfliers=False,  # 不单独显示离群点(因为后面会用散点图显示)
        notch=True,  # 显示中位数置信区间缺口
        # 中位数线属性设置
        medianprops={'color': 'black', 'linewidth': 3},
        # 箱体属性设置
        boxprops={'facecolor': box_colors[i], 'edgecolor': violin_colors[i], 'linewidth': 3},
        # 须线属性设置
        whiskerprops={'color': violin_colors[i], 'linewidth': 3},
        # 端点线属性设置
        capprops={'color': violin_colors[i], 'linewidth': 3}
    )

    # ----------------- 3.2 绘制半小提琴图 -----------------
    # 小提琴图位置向右微调(与箱线图对称)
    violin_pos = positions[i] + box_width / 50

    # 绘制完整小提琴图(violinplot)
    violin = ax.violinplot(
        data_points,
        positions=[violin_pos],  # 指定位置
        widths=violin_width,  # 设置宽度
        showmeans=False,  # 不显示均值
        showmedians=False,  # 不显示中位数(箱线图已显示)
        showextrema=False  # 不显示极值
    )

    # 修改小提琴图只显示右侧一半
    for pc in violin['bodies']:
        # 设置小提琴图颜色和透明度
        pc.set_facecolor(violin_colors[i])
        pc.set_edgecolor(violin_colors[i])
        pc.set_alpha(0.35)  # 设置透明度

        # 获取路径顶点
        vertices = pc.get_paths()[0].vertices
        # 只保留x坐标大于中心位置的部分(实现半小提琴图效果)
        vertices[:, 0] = np.where(
            vertices[:, 0] > violin_pos,
            vertices[:, 0],
            violin_pos
        )

    # ----------------- 3.3 添加数据点 -----------------
    # 在箱形图位置添加抖动点(jitter scatter plot)
    ax.scatter(
        # x坐标:在箱线图位置附近添加随机抖动(避免点重叠)
        np.random.normal(positions[i] - box_width, 0.04, len(data_points)),
        # y坐标:实际数据值
        data_points,
        color=violin_colors[i],  # 颜色与小提琴图一致
        alpha=0.8,  # 透明度
        s=50,  # 点大小
        edgecolor='white',  # 边缘颜色
        linewidth=0.8,  # 边缘线宽
        zorder=3  # 图层顺序(确保点在最上层)
    )

# ==================== 4. 图表美化 ====================
# 设置x轴刻度位置和标签
ax.set_xticks(positions)
ax.set_xticklabels(categories, fontsize=20)

# 设置y轴标签和刻度标签字体大小(修复警告的部分)
ax.set_ylabel('Density', fontsize=20)
# 直接设置刻度标签的字体大小,而不是重新设置标签
plt.yticks(fontsize=20)

# 添加y轴网格线(虚线,半透明)
ax.grid(axis='y', linestyle='--', alpha=0.7)

# 显示边框
for spine in ['top', 'right', 'bottom', 'left']:
    ax.spines[spine].set_visible(True)
    ax.spines[spine].set_linewidth(2)  # 设置边框线宽
    ax.spines[spine].set_color('black')  # 设置边框颜色

# 添加图表标题(pad参数控制标题与图的间距)
plt.title('Raincloud plots', pad=20, fontsize=22)

# 调整子图布局(避免元素被裁剪)
plt.tight_layout()

# 保存图片为600 DPI的PNG格式
plt.savefig(r'E:\PythonProjects\experiments_figures\experiments_figures\云雨图\云雨图.png',
            dpi=600,
            bbox_inches='tight',
            pad_inches=0.2)

# 显示图表
plt.tight_layout()
plt.show()
云雨图

5 单类别散点矩阵图

# 导入必要的库
import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
from scipy.stats import pearsonr
from matplotlib.colors import to_rgba

# Load data
file_path = r'E:\PythonProjects\experiments_figures\experiments_figures\单类别散点矩阵图\data.xlsx'
df = pd.read_excel(file_path, engine='openpyxl', sheet_name='Sheet1', header=0)


columns = variables = labels = ['A', 'B', 'C', 'D', 'E']
# color_list = ['#E7B800', '#91a721', '#02AFBB']  # 设置颜色
# color_list = ['#FCE38A', '#F38181', '#95E1D3']
color_list = ['#00AFBB', '#E7B800', '#FC4E07']
# color_list = ['#F84914', '#59187E', '#2FB4AF']
# color_list = ['#FA6494', '#C97BEF', '#80D3BA']
# color_list = ['#F8766D', '#7CAE00', '#00BFC4']
# color_list = ['#CC4678FF', '#0D0887FF', '#F0F921FF']
col = len(columns)  # 变量个数

# P值的影响
def calculate_p(p_value):
    if p_value < 0.001:
        return '***'
    elif p_value < 0.01:
        return '**'
    elif p_value < 0.05:
        return '*'
    else:
        return ''


# 创建画布
fig, axes = plt.subplots(col + 1, col + 1, figsize=((col + 1) * 3, (col + 1) * 3))
fig.subplots_adjust(hspace=0.1, wspace=0.1)

# 设置图形格式
for i, row_var in enumerate(columns):
    for j, col_var in enumerate(columns):
        ax = axes[i, j]

        # KDE 绘制
        if i == j:
            sns.kdeplot(data=df, x=col_var, ax=ax, alpha=0.6,
                        fill=True, color=color_list[0], linewidth=0)
            if ax.get_legend():
                ax.get_legend().remove()

        # 下三角:带回归线的散点图
        elif i > j:
            sns.scatterplot(data=df, x=col_var, y=row_var,
                            color=color_list[1], ax=ax, s=40, edgecolor='none', alpha=0.8)
            sns.regplot(data=df, x=col_var, y=row_var, ax=ax,
                        color=color_list[1], scatter=False, truncate=False)
            if ax.get_legend():
                ax.get_legend().remove()

        # 上三角:相关信息
        elif j > i:
            ax.set_facecolor(to_rgba(color_list[2], alpha=0.2))
            ax.set_xticks([])
            ax.set_yticks([])
            overall_corr, overall_p = pearsonr(df[row_var], df[col_var])
            stars = calculate_p(overall_p)
            ax.text(0.5, 0.5, f"Cor : {overall_corr:.3f}\n{stars}", ha='center',
                    va='center', fontsize=16, family='Times New Roman', fontweight='bold')

# 增加第6列(箱形图+半个小提琴图)和第6行(直方图)
for i, row_var in enumerate(columns):
    if i < col:
        # 第六栏云雨图
        ax = axes[i, col]
        subset_data = df[row_var]
        center_pos = 0
        box_width = 0.15  # 箱子宽度
        violin_width = 0.6  # 小提琴宽度

        # 添加抖动的点
        jitter = np.random.normal(loc=center_pos - box_width, scale=0.04, size=len(subset_data))
        ax.scatter(jitter, subset_data, s=20,
                   facecolor=color_list[2], edgecolor='black',
                   linewidth=0.5, alpha=0.8, zorder=3)

        # 箱图
        ax.boxplot(subset_data, positions=[center_pos], manage_ticks=False,
                   patch_artist=True, widths=box_width,
                   medianprops={'color': 'white', 'linewidth': 2},
                   boxprops={'facecolor': color_list[2], 'alpha': 0.7},
                   whiskerprops={'color': color_list[2], 'linewidth': 2},
                   capprops={'color': color_list[2], 'linewidth': 2},
                   showfliers=False, zorder=2)

        # 小提琴图
        violin = ax.violinplot(
            subset_data,
            positions=[center_pos],
            widths=violin_width,
            showmeans=False,
            showmedians=False,
            showextrema=False,
        )

        # 修改小提琴情节,只显示右半部分
        for pc in violin['bodies']:
            pc.set_facecolor(color_list[2])
            pc.set_edgecolor(color_list[2])
            pc.set_alpha(0.3)
            vertices = pc.get_paths()[0].vertices
            vertices[:, 0] = np.where(vertices[:, 0] > center_pos, vertices[:, 0], center_pos)

        ax.set_xticks([])
        ax.set_xlim(-0.6, 0.6)

    if i < col:  # 检查避免越界
        # 第6行(直方图)
        ax = axes[col, i]
        sns.histplot(data=df, x=row_var, bins=15, shrink=0.8, color=color_list[1], ax=ax, alpha=0.9)
        if ax.get_legend():
            ax.get_legend().remove()

# 在位置[ 5、5 ] (第6行,第6列)处添加组合雨云图
ax = axes[col, col]
ax.clear()

# 为雨云图设置变量和位置
# variables = ['A', 'B', 'C', 'D', 'E']
positions = np.arange(len(variables))
data_columns = columns[:5] if len(columns) >= 5 else columns

# 对每个变量进行绘图
for i, (var_name, col_name) in enumerate(zip(variables, data_columns)):
    if col_name in df.columns:
        data = df[col_name].dropna().values

        # 对于这个变量的定位
        pos = positions[i]

        # 1. 添加箱线图
        box_parts = ax.boxplot([data], positions=[pos], widths=0.2, patch_artist=True,
                               showfliers=False, medianprops={'color': 'white', 'linewidth': 1.5})
        for box in box_parts['boxes']:
            # box.set(facecolor=color_list[i % len(color_list)], alpha=0.7)
            box.set(facecolor=color_list[0], alpha=0.7)
        # 2. 添加抖动点
        jitter = np.random.normal(loc=pos, scale=0.08, size=len(data))
        ax.scatter(jitter, data, s=15, alpha=0.7,
                   # color=color_list[i % len(color_list)],
                   color=color_list[0],
                   edgecolor='black', linewidth=0.4)

# 设置标签和样式
ax.set_xticks(positions)
ax.set_xticklabels(variables, fontsize=14, family='Times New Roman')

ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)

for i in range(col + 1):
    for j in range(col + 1):
        ax = axes[i, j]
        ax.set_xlabel('')
        ax.set_ylabel('')

        # 添加标题
        if i == 0 and j < col:
            ax.set_title(columns[j], fontsize=16, pad=15)
        if j == 0 and i < col:
            ax.set_ylabel(columns[i], fontsize=16, labelpad=15)

        ax.spines['top'].set_visible(False)
        ax.spines['right'].set_visible(False)
        if i < j and j < col:
            ax.spines['left'].set_visible(False)
            ax.spines['bottom'].set_visible(False)


# labels = ['A', 'B', 'C', 'D', 'E']
# 为第六列(索引5)的行1-5(索引0-4)添加x轴标签
for i in range(min(5, col)):  # 确保不超过列数
    ax = axes[i, col]  # 获取第i行第6列的坐标轴
    ax.set_xticks([0])  # 在位置0设置刻度
    ax.set_xticklabels([labels[i]], fontsize=14, family='Times New Roman')  # 设置标签
    ax.set_xlim(-0.6, 0.6)  # 调整x轴范围确保标签可见

# 为第六行(索引5)的列1-5(索引0-4)添加x轴标签
for j in range(min(5, col)):  # 确保不超过列数
    ax = axes[col, j]  # 获取第6行第j列的坐标轴
    ax.set_xticks([])  # 清除现有刻度
    ax.set_xticks([df[columns[j]].mean()])  # 在均值位置设置刻度
    ax.set_xticklabels([labels[j]], fontsize=14, family='Times New Roman')

# 保存图片为600 DPI的PNG格式
plt.savefig(r'E:\PythonProjects\experiments_figures\experiments_figures\单类别散点矩阵图\单类别散点矩阵图.png',
            dpi=600,
            bbox_inches='tight',
            pad_inches=0.2)

# 显示图表
plt.tight_layout()
plt.show()
单类别散点矩阵图

6 环形热图

# 导入必要的库
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.colors as mcolors
import pandas as pd
import circlify
from matplotlib.patches import Rectangle
import warnings

# 过滤tight_layout与极坐标图不兼容的警告
warnings.filterwarnings("ignore", message="This figure includes Axes that are not compatible with tight_layout")

# --------- 生成示例数据 ---------
try:
    # 尝试读取Excel数据
    df = pd.read_excel('data.xlsx', engine='openpyxl',
                       sheet_name='Sheet1', header=0, index_col=0)
except Exception as e:
    print(f"读取文件出错: {e}")
    print("使用随机生成的数据进行演示")
    np.random.seed(40)
    pathways = [f"Pathway_{i + 1}" for i in range(50)]
    samples = ['A', 'B', 'C']
    data = np.round(np.random.uniform(-1, 1, (len(pathways), len(samples))), 3)
    df = pd.DataFrame(data, index=pathways, columns=samples)

# 颜色配置
color = ["#81D4FA", "white", "#EC407A"]


# --------- 环形热图绘制 ---------
def circular_heatmap(df, gap_after=20, color_map=None, figsize=(10, 10), save_path='环形热图.png'):
    n_rows, n_cols = df.shape
    theta_gap = np.deg2rad(gap_after)
    cell_width = (2 * np.pi - theta_gap) / n_rows

    if color_map is None:
        color_map = mcolors.LinearSegmentedColormap.from_list(
            'custom', color)

    norm = mcolors.Normalize(vmin=-1, vmax=1)
    fig, ax = plt.subplots(figsize=figsize, subplot_kw={'polar': True})

    # 计算最外层热图的半径
    max_radius = 1 + (n_cols - 1) * 0.2 + 0.18
    # 标签半径设置为热图外围
    label_radius = max_radius + 0.2

    # 绘制每个样本组的圆环层
    for col_idx, col in enumerate(df.columns):
        radius = 1 + col_idx * 0.2
        for row_idx, (row_name, row) in enumerate(df.iterrows()):
            theta_start = row_idx * cell_width
            theta_end = theta_start + cell_width
            val = row[col]
            ax.bar(
                (theta_start + theta_end) / 2, 0.18, width=cell_width * 0.9,
                bottom=radius, color=color_map(norm(val)),
                edgecolor='white', linewidth=1, align='center'
            )

    # 添加路径名(列名)- 放置在热图外围
    for row_idx, row_name in enumerate(df.index):
        theta = row_idx * cell_width + cell_width / 2
        text_angle = np.rad2deg(theta)

        # 根据角度调整文本的对齐方式和旋转
        if 0 <= text_angle < 90:
            ha, va = 'left', 'bottom'
            rotation = text_angle
        elif 90 <= text_angle < 180:
            ha, va = 'right', 'bottom'
            rotation = text_angle
        elif 180 <= text_angle < 270:
            ha, va = 'right', 'top'
            rotation = text_angle - 180
        else:  # 270 <= text_angle <= 360
            ha, va = 'left', 'top'
            rotation = text_angle - 180

        ax.text(theta, label_radius, row_name,
                ha=ha, va=va,
                rotation=rotation,
                fontsize=10, color='black')

    # 添加样本名(行名)
    for col_idx, col in enumerate(df.columns):
        ax.text(-theta_gap / 2, 1 + col_idx * 0.2 + 0.09, col,
                ha='left', va='center', fontsize=12, color='black', rotation=90)

    # 图例 - 调整colorbar位置和大小
    sm = plt.cm.ScalarMappable(cmap=color_map, norm=norm)
    sm.set_array([])

    # 创建一个新的axes来放置colorbar
    cbar_ax = fig.add_axes([0.48, 0.32, 0.03, 0.3])

    # 创建colorbar
    cbar = fig.colorbar(sm, cax=cbar_ax)
    cbar.set_label('Value', fontsize=18)
    cbar.ax.tick_params(labelsize=16)

    # 设置轴的限制
    ax.set_rlim(0, label_radius + 0.5)

    # 其它美化
    ax.set_axis_off()
    plt.suptitle('Circular Heatmap', fontsize=20, y=0.97)

    # 保存图片 - 现在有默认路径,会自动保存
    plt.savefig(save_path, dpi=600, bbox_inches='tight', pad_inches=0.2)
    print(f"图片已保存至: {save_path}")

    # 显示图表
    plt.show()
    return fig, ax


# 调用函数生成环形热图 - 不指定路径将使用默认的'relative_path_heatmap.png'
circular_heatmap(df)

# 如果需要自定义保存路径,可以这样调用:
# circular_heatmap(df, save_path='自定义名称.png')
环形热图

7 直方热图

# 导入必要的库
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

# 设置中文字体支持(解决中文显示问题)
plt.rcParams["font.family"] = ["SimHei"]  # 使用黑体
plt.rcParams['axes.unicode_minus'] = False  # 解决负号显示为方块的问题

# ================== 数据准备阶段 ==================

# 读取Excel数据 - 使用index_col=0来将第一列设置为索引
data = pd.read_excel(r'E:\PythonProjects\experiments_figures\experiments_figures\直方热图\data.xlsx',
                     engine='openpyxl',
                     sheet_name='Sheet1',
                     index_col=0)  # 这里设置第一列为索引,也就是A到J这些字母

# 计算每个特征的统计量(这里使用F1列作为示例)
feature_stats = data.mean(axis=1)
color = 'PiYG'
# color = 'coolwarm'
# color = 'YlGn'
# color = 'RdYlGn'
# color = 'PuOr'

# ================== 创建复合图形 ==================

# 设置每个正方形单元格的大小(以英寸为单位)
cell_size_inches = 0.5  # 可以调整这个值来改变正方形大小

# 计算图形的总大小,基于数据尺寸和期望的单元格大小
rows, cols = data.shape
fig_width = (cell_size_inches * cols) * 2   # 增加50%的宽度用于直方图
fig_height = cell_size_inches * rows + 1  # 加额外空间给标题和标签

# 创建图形
fig = plt.figure(figsize=(fig_width, fig_height))

# 创建热图的轴 - 左侧
ax_heatmap = fig.add_axes([0.1, 0.15, 0.6, 0.7])  # [left, bottom, width, height]

# 创建横向条形图的轴 - 右侧
ax_bar = fig.add_axes([0.63, 0.15, 0.2, 0.7])  # 与热图相同的高度和垂直位置

# 创建颜色棒的轴
cbar_ax = fig.add_axes([0.85, 0.32, 0.03, 0.3])  # 颜色棒位置

# ================== 绘制热图 ==================

heatmap = sns.heatmap(data,
            ax=ax_heatmap,
            annot=True,  # 显示数值
            cmap=color,  # 使用选定的颜色映射
            fmt='.1f',   # 数值格式化为一位小数
            linewidths=0.5,  # 网格线宽度
            square=True,  # 确保单元格为正方形
            cbar_ax=cbar_ax,  # 使用指定的颜色棒轴
            cbar_kws={
                'label': 'Value',  # 颜色棒标签
                'orientation': 'vertical',  # 颜色棒方向
            })

ax_heatmap.set_title('Heatmap', fontsize=14)
ax_heatmap.set_xlabel('Group', fontsize=12)
ax_heatmap.set_ylabel('Classification', fontsize=12)

# ================== 绘制横向条形图 ==================

# 获取热图的颜色映射 - 使用新的方法替代get_cmap
cmap = plt.colormaps[color]

# 归一化特征值到[0,1]范围,用于颜色映射
norm = plt.Normalize(vmin=data.values.min(), vmax=data.values.max())

# 创建横向条形图,使用热图的颜色映射
bars = ax_bar.barh(y=feature_stats.index,
                   width=feature_stats.values,
                   height=0.8,
                   color=[cmap(norm(value)) for value in feature_stats.values])

# 反转y轴,使顺序与热图一致
ax_bar.invert_yaxis()

# 为每个条形添加标签,显示具体数值
for i, v in enumerate(feature_stats.values):
    offset = max(feature_stats.values) * 0.45  # 使用最大值的45%作为偏移
    ax_bar.text(v - offset, i, f'{v:.1f}', va='center', fontsize=10,
                color='black' if norm(v) > 0.4 else 'white')  # 根据背景色调整文字颜色

# 添加标题和标签
ax_bar.set_xlabel('Mean Value', fontsize=12)
ax_bar.set_ylabel('')  # 隐藏y轴标签,因为热图已经有标签

# 设置横轴刻度个数
x_min = 0
x_max = max(feature_stats.values) * 1.2  # 留出20%的空白
num_ticks = 3  # 设置想要的刻度数量
x_ticks = np.linspace(x_min, x_max, num_ticks)
ax_bar.set_xticks(x_ticks)
ax_bar.set_xticklabels([f'{x:.1f}' for x in x_ticks])  # 格式化刻度标签

# 获取热图的y轴范围
heatmap_y_min, heatmap_y_max = ax_heatmap.get_ylim()

# 设置条形图的y轴范围与热图一致
ax_bar.set_ylim(heatmap_y_min-0.5, heatmap_y_max-0.5)

# 隐藏条形图的y轴标签,避免重复
ax_bar.set_yticklabels([])

# 保存图片为600 DPI的PNG格式
# 移除tight_layout,因为手动创建的轴不兼容
plt.savefig(r'E:\PythonProjects\experiments_figures\experiments_figures\直方热图\直方热图.png',
            dpi=600,
            bbox_inches='tight',
            pad_inches=0.2)

# 显示图表
plt.show()
直方热图

8 相关性热图

# 导入必要的库
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from matplotlib.patches import Wedge
from matplotlib.colors import LinearSegmentedColormap


def correlation_pie_plot(corr_matrix, figsize=(8, 6), radius=1.0):
    """
    创建相关性矩阵可视化图
    上三角显示数值,下三角显示饼图状圆形,对角线显示完全相关(值为1)的彩色圆形

    参数:
    -----------
    corr_matrix : pandas DataFrame
        相关性矩阵
    radius : float
        圆形的半径(默认: 1.0)
    """
    # 获取变量数量
    n_vars = len(corr_matrix.columns)

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

    # 设置颜色映射 - 使用Viridis颜色方案
    # Viridis是从深紫色(#440154)到亮黄色(#fde725)的渐变色系
    colors = ["#81D4FA", "white", "#EC407A"]
    # colors = ["#440154", "#482878", "#3e4989", "#31688e", "#26828e",
    #           "#1f9e89", "#35b779", "#6ece58", "#b5de2b", "#fde725"]
    # colors = ["#8e0152", "#c51b7d", "#f1b6da","#f7f7f7",  # 中性白
    #           "#e6f5d0", "#b8e186", "#4d9221"]  # 绿色系
    # colors = ["#9e0142", "#d53e4f", "#f46d43", "#fdae61", "#fee08b",
    #           "#ffffbf", "#e6f598", "#abdda4", "#66c2a5", "#3288bd", "#5e4fa2"]

    # 创建线性分段颜色映射,将颜色列表转换为颜色映射对象
    cmap = LinearSegmentedColormap.from_list("custom_diverging", colors)

    # 绘制相关性矩阵
    for i in range(n_vars):
        for j in range(n_vars):
            # 获取当前位置的皮尔逊相关系数值
            corr_val = corr_matrix.iloc[i, j]

            # 上三角区域 - 显示数值文本
            if i < j:
                # 根据相关系数正负选择文本颜色:正相关用深色,负相关用亮色
                text_color = colors[-1] if corr_val > 0 else colors[0]
                ax.text(i, j, f"{corr_val:.2f}", ha='center', va='center',
                        color=text_color, fontsize=12, fontweight='bold')

            # 对角线区域 - 显示完全相关(值为1)的彩色圆形
            elif i == j:
                # 绘制填充圆形,颜色表示完全相关(值为1)
                # cmap(1.0)获取颜色映射中最大值对应的颜色(亮黄色)
                circle = plt.Circle((i, j), radius,
                                    color=cmap(1.0))
                ax.add_artist(circle)

                # 在圆形中心添加黑色文本"1.00"
                ax.text(i, j, "1.00", ha='center', va='center',
                        color='black', fontsize=12, fontweight='bold')

            # 下三角区域 - 显示饼图状相关性圆形
            elif i > j:
                # 绘制空心的灰色边框圆形
                circle = plt.Circle((i, j), radius, fill=False, edgecolor='gray')
                ax.add_artist(circle)

                # 添加楔形(饼图切片)来表示相关性程度
                if corr_val != 0:
                    # 将相关系数转换为角度(0到360度)
                    # 绝对值越大,扇形角度越大
                    angle = abs(corr_val) * 360

                    # 创建指定半径的楔形
                    # width=radius 使楔形填充整个圆形
                    # 颜色根据相关系数值在颜色映射中的位置确定
                    wedge = Wedge((i, j), radius, 0, angle,
                                  width=radius,
                                  color=cmap((corr_val + 1) / 2))
                    ax.add_artist(wedge)

    # 设置刻度和坐标轴范围,为圆形添加适当的边距
    padding = radius * 1.5  # 额外的边距,使图形更美观
    ax.set_xticks(range(n_vars))  # 设置x轴刻度位置
    ax.set_yticks(range(n_vars))  # 设置y轴刻度位置
    # 设置x轴标签,旋转45度并右对齐,字体大小14
    ax.set_xticklabels(corr_matrix.columns, rotation=45, ha='right', fontsize=14)
    # 设置y轴标签,字体大小14
    ax.set_yticklabels(corr_matrix.columns, fontsize=14)
    # 设置x轴和y轴的范围,考虑边距
    ax.set_xlim(-padding, n_vars - 1 + padding)
    ax.set_ylim(n_vars - 1 + padding, -padding)  # y轴反向,使矩阵从上到下排列

    # 添加颜色条
    # 创建可映射的颜色对象,设置颜色映射和数值范围(-1到1)
    sm = plt.cm.ScalarMappable(cmap=cmap, norm=plt.Normalize(-1, 1))
    sm.set_array([])  # 设置空数组
    # 添加颜色条到图形,shrink=0.8使颜色条稍微缩小
    cbar = plt.colorbar(sm, ax=ax, shrink=0.8)
    cbar.set_label('Correlation Coefficient', fontsize=14)  # 设置颜色条标签

    # 设置标题和布局
    plt.title('Correlation Matrix', fontsize=18)  # 设置图形标题
    plt.tight_layout()  # 自动调整布局,防止标签被截断

    return fig, ax  # 返回图形和坐标轴对象


# 使用示例数据
# 从Excel文件读取数据
df = pd.read_excel(r'E:\PythonProjects\experiments_figures\experiments_figures\相关性热图\data.xlsx',
                   engine='openpyxl', sheet_name='Sheet1', header=0)

# 计算皮尔逊相关系数矩阵
# method='pearson'指定使用皮尔逊相关系数(默认就是pearson)
corr = df.corr(method='pearson')

# 创建相关性图,设置图形大小为10x8英寸,圆形半径为0.4
fig, ax = correlation_pie_plot(corr, figsize=(10, 8), radius=0.4)

# 保存图片为600 DPI的PNG格式
plt.savefig(r'E:\PythonProjects\experiments_figures\experiments_figures\相关性热图\相关性热图.png',
            dpi=600,
            bbox_inches='tight',
            pad_inches=0.2)

# 显示图表
plt.tight_layout()
plt.show()
相关性热图

9 边际直方图

# 导入必要的库
import pandas as pd
import seaborn as sns
import numpy as np
import matplotlib.pyplot as plt

'''读取xlsx文件'''
data = pd.read_excel(r'E:\PythonProjects\experiments_figures\experiments_figures\边际直方图/data.xlsx',
                     engine='openpyxl',
                     sheet_name='Sheet1',
                     header=0)

# 输出前5行数据
print(data.head())

# 定义要分析的变量
x = 'F2'  # x轴变量
y = 'target'  # y轴变量

# 定义一套美观的紫色系配色方案
color_scheme = {
    'hex': '#6A0DAD',        # 深紫色
    'kde_fill': '#9370DB',   # 中紫色
    'reg': '#BA55D3',        # 亮紫色
    'kde_contour': '#8A2BE2',# 紫蓝色
    'hist': '#9932CC'        # 暗紫色
}

#%%
"绘制多边形分布图形"
sns.set(style="white", font_scale=2.5,
        rc={"axes.linewidth": 2, "axes.edgecolor": "black"},
        font=['Times New Roman'])

g = sns.jointplot(x=x, y=y,
                  data=data,
                  color=color_scheme['hex'],
                  marginal_kws=dict(bins=30,
                                    kde=True,
                                    color=color_scheme['hex']
                                   ),
                  kind='hex',
                  joint_kws={'gridsize': 30}
                 )

g.fig.set_size_inches(12, 10)
g.savefig(r'E:\PythonProjects\experiments_figures\experiments_figures\边际直方图\hex_plot.png', dpi=600, format='png')
plt.show()

#%%
"绘制核密度分布图形"
sns.set(style="white", font_scale=2.5,
        rc={"axes.linewidth": 2, "axes.edgecolor": "black"},
        font=['Times New Roman'])

# 移除了被contourf忽略的linewidths参数,消除警告
g = sns.jointplot(x=x, y=y,
                  data=data,
                  color=color_scheme['kde_fill'],
                  kind='kde',
                  marginal_kws=dict(fill=True,
                                    color=color_scheme['kde_fill']),
                  joint_kws={'gridsize': 15, 'fill': True}  # 移除linewidths参数
                 )

g.fig.set_size_inches(12, 10)
g.savefig(r'E:\PythonProjects\experiments_figures\experiments_figures\边际直方图\kde_fill_plot.png', dpi=600, format='png')
plt.show()


#%%
"绘制散点分布图形"
sns.set(style="white", font_scale=2.5,
        rc={"axes.linewidth": 2, "axes.edgecolor": "black"},
        font=['Times New Roman'])

g = sns.jointplot(x=x, y=y,
                  data=data,
                  color=color_scheme['reg'],
                  kind='reg'
                 )

g.fig.set_size_inches(12, 10)
g.savefig(r'E:\PythonProjects\experiments_figures\experiments_figures\边际直方图\scatter_reg_plot.png', dpi=600, format='png')
plt.show()


#%%
"绘制密度分布图形"
sns.set(style="white", font_scale=2.5,
        rc={"axes.linewidth": 2, "axes.edgecolor": "black"},
        font=['Times New Roman'])

g = sns.jointplot(x=x, y=y,
                  data=data,
                  color=color_scheme['kde_contour'],
                  kind='kde',
                  levels=12,
                  linewidths=3
                 )

# 调整边际图的KDE线宽
g.ax_marg_x.lines[0].set_linewidth(3)
g.ax_marg_y.lines[0].set_linewidth(3)

g.fig.set_size_inches(12, 10)
g.savefig(r'E:\PythonProjects\experiments_figures\experiments_figures\边际直方图\density_contour_plot.png', dpi=600, format='png')
plt.show()

#%%
"绘制直方点分布图形"
sns.set(style="white", font_scale=2.5,
        rc={"axes.linewidth": 2, "axes.edgecolor": "black"},
        font=['Times New Roman'])

g = sns.jointplot(x=x, y=y,
                  data=data,
                  color=color_scheme['hist'],
                  kind='hist'
                 )

g.fig.set_size_inches(12, 10)
g.savefig(r'E:\PythonProjects\experiments_figures\experiments_figures\边际直方图\histogram_plot.png', dpi=600, format='png')
plt.show()
等高线式密度联合分布图
六边形联合分布图
散点回归联合分布图
填充式核密度联合分布图
直方图联合分布图

网站公告

今日签到

点亮在社区的每一天
去签到