pythonic生物人

matplotlib图表局部区域放大

局部放大散点图是一种在主图中标记出感兴趣的局部区域,并通过单独的子图对这些区域进行放大的可视化方法。它的特点是通过细节放大,帮助观察者更清晰地了解数据的特定部分,而不会丢失整体数据的全貌。

matplotlib实现局部放大散点图,主要使用其中的scatter、Rectangle、add_patch、ConnectionPatch等方法:

  • scatter是matplotlib中用于绘制散点图的方法。
  • Rectangle用于在图表中绘制矩形。
  • add_patch是Axes对象的方法,用于将Patch对象(如Rectangle、Circle 等)添加到图表中。
  • ConnectionPatch用于在两个点之间绘制连接线,常用于连接两个不同的坐标系或图表。

本次举例,将'setosa', 'versicolor', 'virginica'中中位数附近的数据局部放大,

# 9.8_01
# -*- encoding: utf-8 -*-
'''
未经过允许禁止转载!
@Author  :   公众号: pythonic生物人
@Desc    :   9.8 局部放大散点图
'''

import matplotlib.pyplot as plt
import pandas as pd
from matplotlib.patches import Rectangle
from matplotlib.patches import ConnectionPatch

labels = iris['鸢尾花种类']
categories = labels.unique()
colors = {'setosa': '#006a8e', 'versicolor': '#b1283a', 'virginica': '#a8a6a7'}

fig, ax = plt.subplots(figsize=(10, 8), dpi=160)
fig.patch.set_edgecolor('gray')
fig.patch.set_linewidth(0.8)

# 存储各类别中位数信息
medians = {}

for category in categories:
    subset = iris[labels == category]
    ax.scatter(subset['花萼长度 (cm)'],
               subset['花萼宽度 (cm)'],
               label=category,
               color=colors.get(category, 'gray'),
               s=150,
               alpha=0.6)

    # 计算中位数
    median_x = subset['花萼长度 (cm)'].median()
    median_y = subset['花萼宽度 (cm)'].median()
    medians[category] = (median_x, median_y)

    # 标记中位数点
    ax.scatter(median_x,
               median_y,
               color='black',
               s=100,
               edgecolor='white',
               zorder=15)
    ax.text(median_x,
            median_y,
            f'{category[:3]}',
            color='black',
            fontsize=8,
            ha='center',
            va='center')
ax.set_title("局部放大散点图", fontsize=16, fontweight='bold')
ax.set_xlabel('花萼长度 (cm)')
ax.set_ylabel('花萼宽度 (cm)')
ax.legend()

# 创建三个局部放大图
for i, (category, zoom_range) in enumerate(zoom_ranges.items()):
    zoom_x_min, zoom_x_max, zoom_y_min, zoom_y_max = zoom_range

    # 添加矩形框表示局部放大区域
    rect = Rectangle(
        (zoom_x_min, zoom_y_min),
        zoom_x_max - zoom_x_min,
        zoom_y_max - zoom_y_min,
        edgecolor="black",
        facecolor="None",
        linestyle="--",
        linewidth=1.2,
    )
    ax.add_patch(rect)
    # 标记局部放大图中中位数点
    median_x, median_y = medians[category]
    zoom_ax.scatter(median_x,
                    median_y,
                    color='black',
                    s=150,
                    edgecolor='white',
                    zorder=5)
    # 局部放大图中中位数点添加文字注释
    zoom_ax.text(median_x,
                 median_y,
                 f'{category[:3]}',
                 color='black',
                 fontsize=7,
                 ha='center',
                 va='center')
    zoom_ax.set_title(f"{category} 中位数附近局部放大", fontsize=10)

    # 添加连线连接主图和子图中位数点
    con = ConnectionPatch(
        xyA=(median_x, median_y),  # 主图中位数点
        coordsA=ax.transData,
        xyB=(median_x, median_y),  # 子图中位数点
        coordsB=zoom_ax.transData,
        arrowstyle="->",
        color="black",
        linestyle="--",
        linewidth=0.8)
    fig.add_artist(con)

plt.show()

Image

-END-

本期内容「绘图数据+代码+代码详细解释」已上传(点击图片直达代码):

👉Python matplotlib保姆级教程

Image

Image

Image

Image
Image

Image

Image

Image

Image

Image

Image

Image

Image

Image

Image

Image

Image

Image

Image

Image

Image

Image

Image

Image

Image

交流学习

Image