Вопрос или проблема
У меня есть множество графиков, подобно приведенному ниже. Данные получены из измерений, проведенных в разные моменты времени и в разные дни. На графике (который является кумулятивной функцией распределения, если это имеет значение) цвета различают данные, относящиеся к разным дням; маркеры используются для дальнейшего различения данных в пределах каждого дня. Проблема в том, что график очень загроможден и выглядит немного неаккуратно. Некоторые маркеры едва видны.
Вопрос: Есть ли идеи, как лучше отобразить эти данные?
Как вы видите, я пытался разнести маркеры так, чтобы они не находились на одном и том же месте. Код, который я использовал для создания маркеров (с использованием python/matplotlib):
marker_list = ['$A$', '$B$', '$C$', '$D$', '$E$', '$F$', '$G$', '$H$', '$I$', '$J$',
'$K$', '$L$', '$M$', '$N$', '$O$', '$P$', '$Q$', '$R$', '$S$', '$T$',
'$U$', '$V$', '$W$', '$X$', '$Y$', '$Z$', r'$\Gamma$', r'$\Lambda$',
r'$\Omega$', r'$\Psi$',]
'set marker position'
rnd_lst = [np.random.randint(-10, 10) for i, _ in enumerate(marker_list)]
marker_pos = [[25+x, 45+x, 65+x, 87+x] for x in rnd_lst] # фиксированные точки + случайное число для рассеивания маркеров
cc = plt.cycler(marker=marker_list, markevery=marker_pos)
plt.rc('axes', prop_cycle=cc)
plt.rc('lines', markersize=18)
Тем не менее, было бы неплохо “распределить маркеры по оси y”. Например, было бы хорошо показывать маркеры только где CDF выше 0.25.
Вопрос: как ограничить маркеры определенным диапазоном по оси y?
Редактирование
Я думаю, что лучшим вариантом будет использование стилей линий вместо маркеров. Однако использование более 4 или 5 стилей линий тоже плохо, потому что они будут едва различимы друг от друга. Чтобы решить эту проблему, я могу использовать комбинацию стилей линий и маркеров, когда у меня есть более 4-5 линий одного цвета. Проблема с этим решением в том, что оно не дает возможности автоматизировать процесс, по меньшей мере, не используя цикл, как показано выше. Любая помощь в этом будет также оценена 🙂
Вам может быть интересно взглянуть на такие графики с полосами ошибок в seaborn:
https://seaborn.pydata.org/examples/errorband_lineplots.html
Вы могли бы вычислить это для каждого цвета/дня недели. Центральная линия будет средним значением каждого цвета/дня, а тень будет представлять распределение.
Затем, вероятно, лучше рассмотреть дни по отдельности, чтобы сравнить распределения функций. График “коробка-усов” может подойти для сравнения распределений, хотя обычно он используется только для 1-D данных.
Редактирование
Вы можете ограничить ось y с помощью plt.ylim(0.25,1)
, но предыдущий вариант может выглядеть более привлекательно.
Ответ или решение
Конечно, давайте рассмотрим, как улучшить ваш график кумулятивной функции распределения, чтобы сделать его более читабельным и менее загроможденным.
Решение проблемы загроможденности графика
- Ограничение маркеров по оси Y: Чтобы отобразить маркеры только там, где кумулятивная функция распределения превышает 0.25, вы можете добавить дополнительную проверку в ваш код для установки позиций маркеров. Ниже приведен пример, как это можно сделать:
import numpy as np
import matplotlib.pyplot as plt
# Пример данных
x = np.linspace(0, 100, 100)
y = np.random.rand(100) # замените это своими данными
days = ['Day 1', 'Day 2', 'Day 3'] # Пример дней
marker_list = ['o', 's', 'D', '^', 'v', 'x'] # Пример маркеров
colors = ['r', 'g', 'b'] # Пример цветов
for day, color in zip(days, colors):
# Ваши данные
y_day = np.random.rand(100) # Замените на свои данные
y_cdf = np.sort(y_day) # Исходные данные
plt.plot(x, y_cdf, color=color, label=day)
# Установка маркеров только при y > 0.25
for i, val in enumerate(y_cdf):
if val > 0.25:
plt.scatter(x[i], val, marker=np.random.choice(marker_list), color=color)
plt.ylim(0, 1)
plt.legend()
plt.show()
- Использование различных стилей и маркеров: Комбинирование стилей линий и маркеров действительно может помочь улучшить визуализацию. Вы можете использовать
linestyle
иmarker
вместе с циклом.
linestyles = ['-', '--', '-.', ':']
markers = ['o', 's', 'D', '^', 'v']
for day, color in zip(days, colors):
y_day = np.random.rand(100) # Замените на свои данные
y_cdf = np.sort(y_day)
# Выбор линейного стиля
style = np.random.choice(linestyles)
# Построение графика
plt.plot(x, y_cdf, color=color, linestyle=style, label=day)
for i, val in enumerate(y_cdf):
if val > 0.25:
plt.scatter(x[i], val, marker=np.random.choice(markers), color=color)
plt.ylim(0, 1)
plt.legend()
plt.show()
- Использование пакета Seaborn: Если вы предпочитаете более сложные визуализации, такие как графики с полосами погрешности или распределением, стоит рассмотреть использование библиотеки Seaborn. Этот пакет предлагает удобные функции для создания графиков, которые могут автоматически обрабатывать разные уровни значений. Пример:
import seaborn as sns
data = np.random.rand(100, 3) # Вы можете заменить на данные
sns.lineplot(data=data, palette="tab10", linewidth=2.5)
plt.ylim(0.25, 1)
plt.show()
Заключение
Предложенные изменения позволят вам значительно улучшить визуализацию ваших данных, повысить читаемость графиков и улучшить восприятие представленной информации. Не забывайте, что удобочитаемость графика — это ключевой аспект при представлении данных, потому что это помогает лучше понять информацию.