Вопрос или проблема
Рассмотрим простой график
import matplotlib.pyplot as plt
x = [0.9, 1, 1.1, 1.2, 1.3]
y = [0, 0.1, 0.3, 0.6, 1]
plt.plot(x,y)
plt.margins(x=0, y=0)
plt.xlim(0,3)
Это создает линейный график. Отсюда я хотел бы закрасить часть своей оси x так, чтобы от 0 до 0.9 был синий цвет, а от 0.9 до 3 – красный. Одно из решений, которое я придумал, это включить еще два графика: plt.plot([0,0.9], [0,0], color = "b" ,linewidth=3.0)
и
plt.plot([0.9,3.0], [0,0], color = "r",linewidth=3.0)
. Получая следующее изображение:
Это выглядит нормально, но мне это не совсем нравится. Мне ясно, что эти линии не находятся на оси, а скорее чуть выше оси. Вместо этого я хотел бы, чтобы ось и метки принимали соответствующий цвет.
Вы можете использовать вариант метода, описанного здесь, чтобы заменить ось x на пользовательскую сегментированную линию и вручную изменить цвета меток/линий меток:
from matplotlib.collections import LineCollection
ax = plt.gca()
colors = ['b', 'r']
x = [0, .9, 3]
y = [0, 0, 0]
points = np.c_[x, y][:, None]
segments = np.concatenate([points[:-1], points[1:]], axis=1)
lc = LineCollection(segments,colors=colors, linewidth=2,
transform=ax.get_xaxis_transform(),
clip_on=False)
ax.add_collection(lc)
ax.set_ylim(bottom=0)
ax.spines['bottom'].set_visible(False)
for t in ax.get_xticklabels():
t.set_color(colors[int(t.get_position()[0] > 0.9)])
Результат:
Вариант с numpy.searchsorted
, чтобы обрабатывать более чем 2 цвета (используйте 'left'
/'right'
, чтобы изменить, как метка на границе ассоциируется с предыдущим/следующим сегментом):
colors = ['b', 'r', 'g']
x = [0, .9, 2, 3]
y = [0]*len(x)
# [...]
colors_ = np.array(colors)[np.clip(np.searchsorted(x, ax.get_xticks(),
'left')-1,
0, len(colors)-1)]
for c, t, l in zip(colors_,
ax.get_xticklabels(),
ax.get_xticklines()[::2]):
t.set_color(c)
l.set_markeredgecolor(c)
Результат (слева/справа; обратите внимание на цвет 2.0
):
Ответ или решение
Чтобы окрасить части оси X в разных цветах в matplotlib, мы можем воспользоваться методом, основанным на использовании коллекции линий. Это позволяет нам создать ось с сегментированной окраской и управлять цветом меток и линий делений на оси.
Ниже представлен полный код, который иллюстрирует этот подход:
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.collections import LineCollection
x = [0.9, 1, 1.1, 1.2, 1.3]
y = [0, 0.1, 0.3, 0.6, 1]
plt.plot(x, y)
plt.margins(x=0, y=0)
plt.xlim(0, 3)
# Получаем текущую ось
ax = plt.gca()
# Определяем цвета и координаты для оси X
colors = ['b', 'r']
x_segments = [0, 0.9, 3]
y_segments = [0, 0, 0]
# Создаем сегменты с цветами
points = np.c_[x_segments, y_segments][:, None]
segments = np.concatenate([points[:-1], points[1:]], axis=1)
lc = LineCollection(segments, colors=colors, linewidth=4,
transform=ax.get_xaxis_transform(),
clip_on=False)
ax.add_collection(lc)
# Убираем видимость нижней рамки
ax.spines['bottom'].set_visible(False)
# Окрашиваем метки оси X
for t in ax.get_xticklabels():
t.set_color(colors[int(t.get_position()[0] > 0.9)])
# Показываем график
plt.show()
Пояснение кода:
-
Импорт библиотек: Мы используем
matplotlib.pyplot
для создания графиков иnumpy
для удобной работы с массивами. -
Создание графика: Исходный график рисуется с использованием простого вызова
plt.plot()
для заданных массивовx
иy
. -
Настройка сегментов оси X: Мы определяем цвета и координаты. Создается коллекция линий
LineCollection
, которая выглядит как сегментированная линия на оси X. -
Окрашивание меток: Каждый элемент меток оси X окрашивается в зависимости от его положения. Если положение метки больше 0.9, она окрашивается в красный (
r
), в противном случае — в синий (b
). -
Отображение графика: В конце мы вызываем
plt.show()
, чтобы отобразить график с окрашенной осью.
Этот способ позволяет визуализировать разные сегменты оси X более аккуратно и наглядно, чем с добавлением дополнительных линий.
Заключение
Предложенный метод позволяет гибко настраивать цветовые схемы для частей осей в matplotlib, обеспечивая большую свободу для визуализации данных. Вы можете настраивать цвета и деления, добавляя новые элементы, что позволяет создавать более информативные и красивое графическое представление ваших данных.