Рисование замкнутого цикла с Altair mark_line без повторения данных

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

У меня есть набор данных x и y, которые я рисую как диаграмму рассеяния. Затем у меня есть список точечных индексов, которые я хочу соединить линией, которая замыкается сама на себя. Раньше я добивался этого, выполняя .loc[] индексы для создания нового фрейма данных и используя mark_line с order=False. Однако это увеличивает размер моего графика, потому что возвращенный .loc[] фрейм данных хранится в спецификации как второй data объект, повторяющий данные в основном наборе данных.

Я думаю, что «правильный» способ нарисовать эту линию без определения нового фрейма данных — создать новый столбец для использования в качестве параметра order и использовать transform_filter для сокращения только до соответствующих индексов. Однако это оставляет мою линию короче на один сегмент, потому что я не могу вернуться к началу, не повторив всю строку (как я делаю в решении .loc[]).

Есть ли способ закрыть эту строку без создания нового объекта данных? Я также предпочел бы не добавлять повторяющиеся строки в начальный фрейм данных, поскольку он также используется для рендеринга полной диаграммы рассеяния (и некоторых других объектов графика). Моя лучшая мысль сейчас — использовать второй mark_line, но на этот раз с transform_filter, который включает только первый/последний индексы, но это кажется неуклюжим.

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

import pandas as pd
import numpy as np
import altair as alt

# create data
df = pd.DataFrame()
np.random.seed(3)
df['x_data'] = np.random.randint(0,100,(20,))
df['y_data'] = np.random.randint(0,100,(20,))
df = df.reset_index()

# example array of indexes (note that 4 is first and last: the line returns to its start)
line_indexes = [4, 10, 3, 14, 11, 4]

# create scatterplot
scatter_base = alt.Chart(df)
scatter = scatter_base.mark_point().encode(x='x_data', y='y_data')
# create line on a .loc of the same data
line_base = alt.Chart(df.loc[line_indexes])
line = line_base.mark_line(order=False).encode(x='x_data', y='y_data')
# layer
plot_v1 = alt.layer(scatter, line)

# add order column
df['line_order'] = 0
for i, idx in enumerate(line_indexes):
    df.loc[idx, 'line_order'] = i
# create scatterplot
scatter_base = alt.Chart(df)
scatter = scatter_base.mark_point().encode(x='x_data', y='y_data')
# create line with a filter transform and order encoding
line = scatter_base.transform_filter(alt.datum.line_order > 0).mark_line().encode(x='x_data', y='y_data', order='line_order')
# layer
plot_v2 = alt.layer(scatter, line)

Выход Plot_v1: plot_v1 output

Выход Plot_v2: plot_v2 output

Возможно, я недостаточно хорошо понимаю вопрос, но соответствует ли намерению метод добавления конечной точки для закрытия в конец списка индексов сегмента линии? line_indexes = [4, 10, 3, 14, 11];line_indexes.append(line_indexes[0])

r-beginners 09.04.2022 08:58
Анализ настроения постов в Twitter с помощью Python, Tweepy и Flair
Анализ настроения постов в Twitter с помощью Python, Tweepy и Flair
Анализ настроения текстовых сообщений может быть настолько сложным или простым, насколько вы его сделаете. Как и в любом ML-проекте, вы можете выбрать...
7 лайфхаков для начинающих Python-программистов
7 лайфхаков для начинающих Python-программистов
В этой статье мы расскажем о хитростях и советах по Python, которые должны быть известны разработчику Python.
Установка Apache Cassandra на Mac OS
Установка Apache Cassandra на Mac OS
Это краткое руководство по установке Apache Cassandra.
Сертификатная программа "Кванты Python": Бэктестер ансамблевых методов на основе ООП
Сертификатная программа "Кванты Python": Бэктестер ансамблевых методов на основе ООП
В одном из недавних постов я рассказал о том, как я использую навыки количественных исследований, которые я совершенствую в рамках программы TPQ...
Создание персонального файлового хранилища
Создание персонального файлового хранилища
Вы когда-нибудь хотели поделиться с кем-то файлом, но он содержал конфиденциальную информацию? Многие думают, что электронная почта безопасна, но это...
Создание приборной панели для анализа данных на GCP - часть I
Создание приборной панели для анализа данных на GCP - часть I
Недавно я столкнулся с интересной бизнес-задачей - визуализацией сбоев в цепочке поставок лекарств, которую могут просматривать врачи и...
1
1
16
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы можете использовать .mark_line(interpolate='linear-closed') для формирования многоугольника в вашем примере plot_v2. Дополнительную информацию о различных режимах интерполяции можно найти в документации..

Спасибо, это именно то, что мне было нужно! Я, должно быть, пропустил это, потому что я не думаю об этой задаче как об «интерполяции», но я понимаю, почему она хранится в этой опции.

fitzme 10.04.2022 06:18

Другие вопросы по теме