Размещение текстовых блоков в Matplotlib

MatplotlibMatplotlibBeginner
Практиковаться сейчас

This tutorial is from open-source community. Access the source code

💡 Этот учебник переведен с английского с помощью ИИ. Чтобы просмотреть оригинал, вы можете перейти на английский оригинал

Введение

При создании визуализаций данных добавление аннотаций может значительно улучшить понимание графиков пользователями. Текстовые поля - это эффективный способ включения дополнительной информации непосредственно в визуализации. Matplotlib, популярная библиотека Python для создания статических, анимированных и интерактивных визуализаций, предлагает мощные инструменты для добавления настраиваемых текстовых полей в графики.

В этом практическом занятии (лабораторной работе) вы научитесь размещать текстовые поля в графиках Matplotlib с использованием Python. Вы узнаете, как позиционировать текст в координатах осей, что позволяет сохранить текст в фиксированном положении относительно графика, независимо от изменений масштаба данных. Кроме того, вы научитесь настраивать текстовые поля с разными стилями, цветами и уровнями прозрачности с помощью свойства bbox.

К концу этого практического занятия вы сможете создавать информативные и визуально привлекательные графики с стратегически размещенными аннотациями для своих проектов по визуализации данных.

Советы по виртуальной машине (VM)

После завершения запуска виртуальной машины нажмите в левом верхнем углу, чтобы переключиться на вкладку Notebook и получить доступ к Jupyter Notebook для практики.

click-notebook

Вам может потребоваться подождать несколько секунд, пока Jupyter Notebook загрузится. Из-за ограничений Jupyter Notebook автоматизация проверки операций невозможна.

Если вы столкнетесь с какими-либо проблемами во время практического занятия, не стесняйтесь обращаться к Labby за помощью. Мы будем признательны за ваш отзыв после занятия, чтобы помочь нам улучшить опыт проведения практических занятий.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL matplotlib(("Matplotlib")) -.-> matplotlib/BasicConceptsGroup(["Basic Concepts"]) matplotlib(("Matplotlib")) -.-> matplotlib/PlottingDataGroup(["Plotting Data"]) matplotlib(("Matplotlib")) -.-> matplotlib/PlotCustomizationGroup(["Plot Customization"]) matplotlib/BasicConceptsGroup -.-> matplotlib/importing_matplotlib("Importing Matplotlib") matplotlib/BasicConceptsGroup -.-> matplotlib/figures_axes("Understanding Figures and Axes") matplotlib/PlottingDataGroup -.-> matplotlib/histograms("Histograms") matplotlib/PlotCustomizationGroup -.-> matplotlib/titles_labels("Adding Titles and Labels") matplotlib/PlotCustomizationGroup -.-> matplotlib/text_annotations("Text Annotations") subgraph Lab Skills matplotlib/importing_matplotlib -.-> lab-48868{{"Размещение текстовых блоков в Matplotlib"}} matplotlib/figures_axes -.-> lab-48868{{"Размещение текстовых блоков в Matplotlib"}} matplotlib/histograms -.-> lab-48868{{"Размещение текстовых блоков в Matplotlib"}} matplotlib/titles_labels -.-> lab-48868{{"Размещение текстовых блоков в Matplotlib"}} matplotlib/text_annotations -.-> lab-48868{{"Размещение текстовых блоков в Matplotlib"}} end

Создание Jupyter Notebook и подготовка данных

На первом этапе мы создадим новый Jupyter Notebook и подготовим наши данные для визуализации.

Создание нового блокнота

В первой ячейке блокнота импортируем необходимые библиотеки. Введите следующий код и запустите его, нажав кнопку "Run" или нажав Shift+Enter:

import matplotlib.pyplot as plt
import numpy as np
libraries-imported

Этот код импортирует две важные библиотеки:

  • matplotlib.pyplot: Набор функций, которые делают matplotlib похожим на MATLAB
  • numpy: Основной пакет для научных вычислений в Python

Создание примерных данных

Теперь создадим некоторые примерные данные, которые мы будем визуализировать. В новой ячейке введите и запустите следующий код:

## Set a random seed for reproducibility
np.random.seed(19680801)

## Generate 10,000 random numbers from a normal distribution
x = 30 * np.random.randn(10000)

## Calculate basic statistics
mu = x.mean()
median = np.median(x)
sigma = x.std()

## Display the statistics
print(f"Mean (μ): {mu:.2f}")
print(f"Median: {median:.2f}")
print(f"Standard Deviation (σ): {sigma:.2f}")

При запуске этой ячейки вы должны увидеть вывод, похожий на следующий:

Mean (μ): -0.31
Median: -0.28
Standard Deviation (σ): 29.86

Точные значения могут немного отличаться. Мы создали набор данных из 10 000 случайных чисел, сгенерированных из нормального распределения, и вычислили три важные статистические характеристики:

  1. Среднее значение (μ): Среднее значение всех точек данных
  2. Медиана: Значение, находящееся посередине, когда данные упорядочены
  3. Стандартное отклонение (σ): Мера разброса данных

Эти статистические характеристики будут использоваться позже для аннотации нашей визуализации.

Создание простой гистограммы

Теперь, когда у нас есть данные, создадим гистограмму для визуализации их распределения. Гистограмма разбивает данные на интервалы (диапазоны) и показывает частоту точек данных в каждом интервале.

Создание гистограммы

В новой ячейке вашего Jupyter Notebook введите и запустите следующий код:

## Create a figure and axes
fig, ax = plt.subplots(figsize=(10, 6))

## Create a histogram with 50 bins
histogram = ax.hist(x, bins=50, color='skyblue', edgecolor='black')

## Add title and labels
ax.set_title('Distribution of Random Data', fontsize=16)
ax.set_xlabel('Value', fontsize=12)
ax.set_ylabel('Frequency', fontsize=12)

## Display the plot
plt.tight_layout()
plt.show()

При запуске этой ячейки вы должны увидеть гистограмму, отображающую распределение ваших случайных данных. Вывод будет похож на колоколообразную кривую (нормальное распределение), центрированную около нуля.

Понимание кода

Разберем, что делает каждая строка кода:

  1. fig, ax = plt.subplots(figsize=(10, 6)): Создает объект фигуры и объект осей. Параметр figsize задает размер графика в дюймах (ширина, высота).

  2. histogram = ax.hist(x, bins=50, color='skyblue', edgecolor='black'): Создает гистограмму наших данных x с 50 интервалами. Интервалы окрашены в небесно - голубой цвет с черными границами.

  3. ax.set_title('Distribution of Random Data', fontsize=16): Добавляет заголовок к графику с размером шрифта 16.

  4. ax.set_xlabel('Value', fontsize=12) и ax.set_ylabel('Frequency', fontsize=12): Добавляют метки к осям x и y с размером шрифта 12.

  5. plt.tight_layout(): Автоматически подстраивает график под площадь фигуры.

  6. plt.show(): Отображает график.

Гистограмма показывает, как распределены наши данные. Поскольку мы использовали np.random.randn(), которая генерирует данные из нормального распределения, гистограмма имеет колоколообразную форму, центрированную вокруг 0. Высота каждой столбцы представляет количество точек данных, попавших в этот диапазон.

Добавление текстового блока со статистикой

Теперь, когда у нас есть простая гистограмма, усовершенствуем ее, добавив текстовый блок, отображающий статистическую информацию о наших данных. Это сделает визуализацию более информативной для зрителей.

Создание текстового содержимого

Сначала нам нужно подготовить текстовое содержимое, которое будет находиться внутри нашего текстового блока. В новой ячейке введите и запустите следующий код:

## Create a string with the statistics
textstr = '\n'.join((
    r'$\mu=%.2f$' % (mu,),           ## Mean
    r'$\mathrm{median}=%.2f$' % (median,),  ## Median
    r'$\sigma=%.2f$' % (sigma,)       ## Standard deviation
))

print("Text content for our box:")
print(textstr)

Вы должны увидеть вывод, похожий на следующий:

Text content for our box:
$\mu=-0.31$
$\mathrm{median}=-0.28$
$\sigma=29.86$

Этот код создает многострочную строку, содержащую среднее значение, медиану и стандартное отклонение наших данных. Рассмотрим некоторые интересные аспекты этого кода:

  1. Метод \n'.join(...) объединяет несколько строк, вставляя между ними символ новой строки.
  2. Символ r перед каждой строкой делает ее "сырой" строкой, что полезно при использовании специальных символов.
  3. Запись $...$ используется для математического форматирования в стиле LaTeX в matplotlib.
  4. \mu и \sigma - это символы LaTeX для греческих букв μ (му) и σ (сигма).
  5. %.2f - это спецификатор формата, который отображает число с плавающей точкой с двумя знаками после запятой.

Создание и добавление текстового блока

Теперь пересоздадим нашу гистограмму и добавим к ней текстовый блок. В новой ячейке введите и запустите следующий код:

## Create a new figure and axes
fig, ax = plt.subplots(figsize=(10, 6))

## Create a histogram with 50 bins
histogram = ax.hist(x, bins=50, color='skyblue', edgecolor='black')

## Add title and labels
ax.set_title('Distribution of Random Data with Statistics', fontsize=16)
ax.set_xlabel('Value', fontsize=12)
ax.set_ylabel('Frequency', fontsize=12)

## Define the properties of the text box
properties = dict(boxstyle='round', facecolor='wheat', alpha=0.5)

## Add the text box to the plot
## Position the box in the top left corner (0.05, 0.95) in axes coordinates
ax.text(0.05, 0.95, textstr, transform=ax.transAxes, fontsize=14,
        verticalalignment='top', bbox=properties)

## Display the plot
plt.tight_layout()
plt.show()

При запуске этой ячейки вы должны увидеть свою гистограмму с текстовым блоком в левом верхнем углу, отображающим статистику.

Понимание кода для текстового блока

Разберем важные части кода, создающего текстовый блок:

  1. properties = dict(boxstyle='round', facecolor='wheat', alpha=0.5):

    • Это создает словарь с свойствами текстового блока.
    • boxstyle='round': Делает углы блока закругленными.
    • facecolor='wheat': Устанавливает цвет фона блока в цвет пшеницы.
    • alpha=0.5: Делает блок полупрозрачным (50% непрозрачности).
  2. ax.text(0.05, 0.95, textstr, transform=ax.transAxes, fontsize=14, verticalalignment='top', bbox=properties):

    • Это добавляет текст на оси в позиции (0.05, 0.95).
    • transform=ax.transAxes: Это очень важно - это означает, что координаты заданы в единицах осей (от 0 до 1), а не в единицах данных. Таким образом, (0.05, 0.95) означает "на 5% от левого края и на 95% от нижнего края графика".
    • fontsize=14: Устанавливает размер шрифта.
    • verticalalignment='top': Выравнивает текст так, чтобы верхний край текста находился на указанной y - координате.
    • bbox=properties: Применяет наши свойства текстового блока.

Текстовый блок останется в той же позиции относительно осей графика, даже если вы увеличите масштаб графика или измените диапазон данных. Это происходит потому, что мы использовали transform=ax.transAxes, которая использует координаты осей вместо координат данных.

Настройка текстового блока

Теперь, когда мы успешно добавили текстовый блок к нашему графику, исследуем различные параметры настройки, чтобы сделать его более визуально привлекательным и подходящим для разных контекстов.

Эксперименты с разными стилями

Создадим функцию, чтобы упростить эксперименты с разными стилями текстовых блоков. В новой ячейке введите и запустите следующий код:

def plot_with_textbox(boxstyle, facecolor, alpha, position=(0.05, 0.95)):
    """
    Create a histogram with a custom text box.

    Parameters:
    boxstyle (str): Style of the box ('round', 'square', 'round4', etc.)
    facecolor (str): Background color of the box
    alpha (float): Transparency of the box (0-1)
    position (tuple): Position of the box in axes coordinates (x, y)
    """
    ## Create figure and plot
    fig, ax = plt.subplots(figsize=(8, 5))
    ax.hist(x, bins=50, color='skyblue', edgecolor='black')

    ## Set title and labels
    ax.set_title(f'Text Box Style: {boxstyle}', fontsize=16)
    ax.set_xlabel('Value', fontsize=12)
    ax.set_ylabel('Frequency', fontsize=12)

    ## Create text box properties
    box_props = dict(boxstyle=boxstyle, facecolor=facecolor, alpha=alpha)

    ## Add text box
    ax.text(position[0], position[1], textstr, transform=ax.transAxes,
            fontsize=14, verticalalignment='top', bbox=box_props)

    plt.tight_layout()
    plt.show()

Теперь используем эту функцию, чтобы попробовать разные стили блоков. В новой ячейке введите и запустите:

## Try a square box with light green color
plot_with_textbox('square', 'lightgreen', 0.7)

## Try a rounded box with light blue color
plot_with_textbox('round', 'lightblue', 0.5)

## Try a box with extra rounded corners
plot_with_textbox('round4', 'lightyellow', 0.6)

## Try a sawtooth style box
plot_with_textbox('sawtooth', 'lightcoral', 0.4)

При запуске этой ячейки вы увидите четыре разных графика, каждый с разным стилем текстового блока.

Изменение положения текстового блока

Положение текстового блока может быть важным для визуализации. Поместим текстовые блоки в разные углы графика. В новой ячейке введите и запустите:

## Create a figure with a 2x2 grid of subplots
fig, axes = plt.subplots(2, 2, figsize=(12, 10))
axes = axes.flatten()  ## Flatten to easily iterate

## Define positions for the four corners
positions = [
    (0.05, 0.95),  ## Top left
    (0.95, 0.95),  ## Top right
    (0.05, 0.05),  ## Bottom left
    (0.95, 0.05)   ## Bottom right
]

## Define alignments for each position
alignments = [
    ('top', 'left'),          ## Top left
    ('top', 'right'),         ## Top right
    ('bottom', 'left'),       ## Bottom left
    ('bottom', 'right')       ## Bottom right
]

## Corner labels
corner_labels = ['Top Left', 'Top Right', 'Bottom Left', 'Bottom Right']

## Create four plots with text boxes in different corners
for i, ax in enumerate(axes):
    ## Plot histogram
    ax.hist(x, bins=50, color='skyblue', edgecolor='black')

    ## Set title
    ax.set_title(f'Text Box in {corner_labels[i]}', fontsize=14)

    ## Create text box properties
    box_props = dict(boxstyle='round', facecolor='wheat', alpha=0.5)

    ## Add text box
    ax.text(positions[i][0], positions[i][1], textstr,
            transform=ax.transAxes, fontsize=12,
            verticalalignment=alignments[i][0],
            horizontalalignment=alignments[i][1],
            bbox=box_props)

plt.tight_layout()
plt.show()

Этот код создает сетку из четырех гистограмм 2x2, каждая с текстовым блоком в разных углах.

Понимание позиционирования текстового блока

Существует несколько ключевых параметров, которые контролируют позиционирование текстового блока:

  1. Координаты позиции: Координаты (x, y) определяют, где будет размещен текстовый блок. При использовании transform=ax.transAxes они заданы в координатах осей, где (0, 0) - нижний левый угол, а (1, 1) - верхний правый угол.

  2. Вертикальное выравнивание: Параметр verticalalignment контролирует, как текст выравнивается вертикально относительно y - координаты:

    • 'top': Верхний край текста находится на указанной y - координате.
    • 'center': Центр текста находится на указанной y - координате.
    • 'bottom': Нижний край текста находится на указанной y - координате.
  3. Горизонтальное выравнивание: Параметр horizontalalignment контролирует, как текст выравнивается горизонтально относительно x - координаты:

    • 'left': Левый край текста находится на указанной x - координате.
    • 'center': Центр текста находится на указанной x - координате.
    • 'right': Правый край текста находится на указанной x - координате.

Эти параметры выравнивания особенно важны при размещении текста в углах. Например, в правом верхнем углу вы бы хотели использовать horizontalalignment='right', чтобы правый край текста выравнивался с правым краем графика.

Создание финальной визуализации с несколькими текстовыми элементами

На этом последнем этапе мы объединим все, что узнали, чтобы создать комплексную визуализацию, включающую несколько текстовых элементов с разными стилями. Это продемонстрирует, как текстовые блоки можно использовать для улучшения повествования на основе данных.

Создание продвинутой визуализации

Создадим более сложный график, который включает как нашу гистограмму, так и некоторые дополнительные визуальные элементы. В новой ячейке введите и запустите следующий код:

## Create a figure with a larger size for our final visualization
fig, ax = plt.subplots(figsize=(12, 8))

## Plot the histogram with more bins and a different color
n, bins, patches = ax.hist(x, bins=75, color='lightblue',
                           edgecolor='darkblue', alpha=0.7)

## Add title and labels with improved styling
ax.set_title('Distribution of Random Data with Statistical Annotations',
             fontsize=18, fontweight='bold', pad=20)
ax.set_xlabel('Value', fontsize=14)
ax.set_ylabel('Frequency', fontsize=14)

## Add grid for better readability
ax.grid(True, linestyle='--', alpha=0.7)

## Mark the mean with a vertical line
ax.axvline(x=mu, color='red', linestyle='-', linewidth=2,
           label=f'Mean: {mu:.2f}')

## Mark one standard deviation range
ax.axvline(x=mu + sigma, color='green', linestyle='--', linewidth=1.5,
           label=f'Mean + 1σ: {mu+sigma:.2f}')
ax.axvline(x=mu - sigma, color='green', linestyle='--', linewidth=1.5,
           label=f'Mean - 1σ: {mu-sigma:.2f}')

## Create a text box with statistics in the top left
stats_box_props = dict(boxstyle='round', facecolor='lightyellow',
                      alpha=0.8, edgecolor='gold', linewidth=2)

stats_text = '\n'.join((
    r'$\mathbf{Statistics:}$',
    r'$\mu=%.2f$ (mean)' % (mu,),
    r'$\mathrm{median}=%.2f$' % (median,),
    r'$\sigma=%.2f$ (std. dev.)' % (sigma,)
))

ax.text(0.05, 0.95, stats_text, transform=ax.transAxes, fontsize=14,
        verticalalignment='top', bbox=stats_box_props)

## Add an informational text box in the top right
info_box_props = dict(boxstyle='round4', facecolor='lightcyan',
                     alpha=0.8, edgecolor='deepskyblue', linewidth=2)

info_text = '\n'.join((
    r'$\mathbf{About\ Normal\ Distributions:}$',
    r'$\bullet\ 68\%\ of\ data\ within\ 1\sigma$',
    r'$\bullet\ 95\%\ of\ data\ within\ 2\sigma$',
    r'$\bullet\ 99.7\%\ of\ data\ within\ 3\sigma$'
))

ax.text(0.95, 0.95, info_text, transform=ax.transAxes, fontsize=14,
        verticalalignment='top', horizontalalignment='right',
        bbox=info_box_props)

## Add a legend
ax.legend(fontsize=12)

## Tighten the layout and show the plot
plt.tight_layout()
plt.show()

При запуске этой ячейки вы увидите комплексную визуализацию с:

  • Гистограммой данных с улучшенным стилем.
  • Вертикальными линиями, отмечающими среднее значение и диапазон в одну стандартную ошибку.
  • Текстовым блоком со статистикой в левом верхнем углу.
  • Информационным текстовым блоком о нормальных распределениях в правом верхнем углу.
  • Легендой, объясняющей вертикальные линии.

Понимание продвинутых элементов

Рассмотрим некоторые из новых элементов, которые мы добавили:

  1. Вертикальные линии с помощью axvline():

    • Эти линии отмечают важные статистические показатели прямо на графике.
    • Параметр label позволяет включить эти линии в легенду.
  2. Несколько текстовых блоков с разными стилями:

    • Каждый текстовый блок служит разной цели и имеет свой уникальный стиль.
    • Блок со статистикой показывает вычисленные значения из наших данных.
    • Информационный блок предоставляет контекст о нормальных распределениях.
  3. Улучшенный формат:

    • Форматирование LaTeX используется для создания жирного текста с помощью \mathbf{}.
    • Маркеры списка создаются с помощью \bullet.
    • Интервал между строками контролируется с помощью \ (обратный слеш, за которым следует пробел).
  4. Сетка и легенда:

    • Сетка помогает зрителям более точно читать значения с графика.
    • Легенда объясняет смысл цветных линий.

Финальные замечания о размещении текстовых блоков

При размещении нескольких текстовых элементов в визуализации учитывайте:

  1. Визуальную иерархию: Самая важная информация должна быть наиболее заметной.
  2. Позиционирование: Размещайте связанную информацию рядом с соответствующими частями визуализации.
  3. Контраст: Убедитесь, что текст хорошо читается на фоне его фона.
  4. Согласованность: Используйте согласованный стиль для однотипной информации.
  5. Загромождение: Избегайте перегрузки визуализации слишком большим количеством текстовых элементов.

Разумно размещая и стилизуя текстовые блоки, вы можете создать визуализации, которые будут как информативными, так и визуально привлекательными, помогающими зрителям понять ключевые выводы из ваших данных.

Резюме

В этом практическом занятии вы узнали, как эффективно использовать текстовые блоки в Matplotlib для улучшения визуализации данных. Давайте обобщим ключевые моменты:

Основные концепции

  1. Создание базовых текстовых блоков: Вы научились добавлять текстовые блоки на графики с помощью функции matplotlib.pyplot.text() с параметром bbox.
  2. Позиционирование текстовых блоков: Вы узнали, как позиционировать текстовые блоки с использованием координат осей с помощью transform=ax.transAxes, что позволяет фиксировать положение текста независимо от масштабирования данных.
  3. Стилизация текстовых блоков: Вы исследовали, как настраивать текстовые блоки с разными стилями (boxstyle), цветами (facecolor), уровнями прозрачности (alpha) и свойствами границ.
  4. Выравнивание текста: Вы практиковались в использовании параметров verticalalignment и horizontalalignment для правильного позиционирования текста в разных частях визуализации.
  5. Форматирование с использованием LaTeX: Вы использовали обозначения LaTeX для добавления математических символов и форматирования в текст.
  6. Комплексная визуализация: Вы создали полноценную визуализацию, которая объединяет несколько текстовых элементов с разными стилями для создания связанной истории на основе данных.

Практические применения

Техники, которые вы узнали в этом практическом занятии, можно применить для:

  • Добавления статистических сводок к графикам.
  • Метки ключевых характеристик в данных.
  • Предоставления контекста или объяснений в визуализациях.
  • Создания легенд или ключей с настраиваемым форматированием.
  • Выделения важных результатов или выводов.

Следующие шаги

Для дальнейшего улучшения навыков визуализации данных с использованием Matplotlib рекомендуется изучить:

  • Продвинутые техники аннотации, такие как стрелки и аннотационные блоки.
  • Интерактивные текстовые элементы с использованием обработки событий в Matplotlib.
  • Настройку текста с использованием разных шрифтов и стилей.
  • Создание подграфиков с согласованными аннотациями.
  • Сохранение визуализаций с текстовыми элементами для публикации.

Освоив искусство текстовых аннотаций в Matplotlib, вы сможете создавать более информативные и профессиональные визуализации данных, которые эффективно передают ваши выводы аудитории.