#python #python-3.x #pandas #dataframe #data-visualization
#python #python-3.x #pandas #фрейм данных #визуализация данных
Вопрос:
У меня есть фрейм данных (см. Раздел «Тестовые данные» ниже), и я хотел бы добавить дополнительную ось x (вверху). Но эта ось должна быть от 0 до 38,24 (мс). Это сумма всех значений в столбце ‘Время’. Это выражает общее время, которое потребовалось для выполнения 4 выводов. До сих пор я безуспешно пробовал ‘twinx ()’.
Как я могу это сделать? Возможно ли это или мне не хватает информации?
Тестовые данные:
raw_data = {'Time': [21.9235, 4.17876, 4.02168, 3.81504, 4.2972],
'TPU': [33.3, 33.3, 33.3, 33.3, 33.3],
'CPU': [32, 32, 32, 32, 32],
'MemUsed': [435.92, 435.90, 436.02, 436.02, 436.19]}
df_m=pd.DataFrame(raw_data, columns = ['Time', 'TPU', 'CPU', 'MemUsed'])
df_m
##Sum of all values in column Time(ms)
(df_m.iloc[:, 0].sum())
##Time per inference(ms)
ax = df_m.plot(kind = 'line', y = 'MemUsed', grid = True)
ax.set_xlabel("NUMBER OF INFERENCES")
ax.set_ylabel("MemUsed(MB)")
Что я пробовал:
ax = df_m.plot(kind = 'line', y = 'MemUsed', grid = True)
df_m.plot(kind='line', ax=ax.twinx(), secondary_x=range(0, 39))
ax.set_xlabel("NUMBER OF INFERENCES")
ax.set_ylabel("MemUsed(MB)")
Выходной график:
Как выглядит большая таблица
Комментарии:
1. Возможен ли вариант plotly?
2. Конечно. Я никогда не использовал, хотя. Но графики кажутся очень красивыми.
3. Отлично. Я согласен, плотные графики могут быть довольно ошеломляющими. Я добавил ответ для вас и поддержал вопрос для полноты.
Ответ №1:
В дополнение к вашему положительному комментарию относительно plotly, вот пример того, как добиться мультиаксиальности для вашего набора данных.
Код намного проще, чем кажется. Код выглядит «длинным» из-за того, что я отформатировал dict
s для облегчения чтения.
Ключевыми элементами являются:
- Добавление совокупной суммы
time
столбца (time_c
) для использования вxaxis2
. - Добавление скрытой трассировки, которая выравнивается по
xaxis
, и ваших временных данных, которые выравниваются поxaxis2
. Без скрытой трассировки либо обе оси не отображаются, либо они отображаются, но не выровнены из-за того, что отображается только одна трассировка.
(Обновленный) Пример кода:
Следующий код был обновлен для решения проблемы, с которой OP столкнулся с большим набором данных (70 тыс. строк).
Изменение ключа — это обновление для layout['xaxis']
и layout['xaxis2']
dicts, чтобы содержать 'type': 'category'
, 'nticks'
и определенные 'range'
ключи.
import pandas as pd
from plotly.offline import plot
# Create the dataset.
raw_data = {'time': [21.9235, 4.17876, 4.02168, 3.81504, 4.2972],
'tpu': [33.3, 33.3, 33.3, 33.3, 33.3],
'cpu': [32, 32, 32, 32, 32],
'memused': [435.92, 435.90, 436.02, 436.02, 436.19]}
df = pd.DataFrame(raw_data)
df['time_c'] = df['time'].cumsum().round(2)
# Plotting code.
data = []
layout = {'margin': {'t': 105},
'title': {'text': 'Example Showing use of Secondary X-Axis',
'y': 0.97}}
# Create a (hidden) trace for the xaxis.
data.append({'x': df.index,
'y': df['memused'],
'showlegend': False,
'mode': 'markers',
'marker': {'size': 0.001}})
# Create the visible trace for xaxis2.
data.append({'x': df['time_c'],
'y': df['memused'],
'xaxis': 'x2',
'name': 'Inference'})
# Configure graph layout.
nticks = int(df.shape[0] // (df.shape[0] * 0.05))
layout['xaxis'] = {'title': 'Number of Inferences',
'nticks': nticks,
'range': [df.index.min(), df.index.max()],
'tickangle': 45,
'type': 'category'}
layout['xaxis2'] = {'title': 'Time(ms)',
'nticks': nticks,
'overlaying': 'x1',
'range': [df['time_c'].min(), df['time_c'].max()],
'side': 'top',
'tickangle': 45,
'type': 'category'}
layout['yaxis'] = {'title': 'Memory Used (MB)'}
fig = {'data': data, 'layout': layout}
plot(fig, filename='/path/to/graph.html')
Пример графика (исходный набор данных):
Я намеренно опустил любую дополнительную конфигурацию отображения для простоты кода. Однако, ссылаясь на плоттерные документы верхнего уровня, графики легко настраиваются.
Пример графика (новый набор данных):
На этом графике используется синтезированный набор данных (больший, 70 тыс. строк) из другого ответа.
Комментарии:
1. У меня возникают проблемы при использовании большого фрейма данных
2. Это может быть связано с тем, что данные фактически отображаются дважды; Я думаю, у меня есть решение. Похож ли набор данных на то, что вы опубликовали в вопросе? Сколько строк? У меня есть идея для другого подхода xaxis.
3. Да, это похоже. Я добавлю изображение. Имеется 70000 строк
4. Вот так. Я обновил код и графики в исходном ответе, чтобы решить проблему, с которой вы столкнулись. Кроме того, я опубликовал второй ответ (sshhhh), чтобы предоставить вам другой вариант, который устраняет необходимость построения двух трасс по 70 тыс. точек данных каждая. Надеюсь, это поможет!
5. Это сработало. Это быстрее. Я проанализирую ваш код.
Ответ №2:
Хотя в целом это не рекомендуется, я опубликую другой ответ, посвященный новому набору данных, поскольку предыдущий ответ работает с учетом исходного набора данных.
Этот пример отличается от исходного запроса вторичной оси x по двум причинам:
- Из-за размера (нового) набора данных построение «скрытого» слоя данных не является оптимальным.
- Для правильного отображения дополнительной оси x необходимо построить второй тренд, и, учитывая предыдущую причину, это больше не вариант.
Поэтому был использован другой подход — комбинированное обозначение оси x. Вместо построения двух осей на одной оси x отображаются обе обязательные метки.
Пример графика:
Примечание: Это (очевидно) синтезированные данные, чтобы достичь количества строк (70k) в обновленном вопросе.
Пример кода:
import numpy as np
import pandas as pd
from plotly.offline import plot
# Synthesised dataset. (This code can be ignored.)
np.random.seed(0)
a = np.random.exponential(size=70000)*4
t = pd.Series(a).rolling(window=2000, min_periods=50).mean().to_numpy()
r = np.arange(70000).astype(str)
m = t*100
df = pd.DataFrame({'run': r,
'time': t,
'memused': m}).dropna()
# Add cumulative time column.
df['time_c'] = df['time'].cumsum().round(1)
# --- Graphing code starts here ---
def create_labels(x):
"""Function to create xaxis labels."""
return f"({x['run']}): {x['time_c']}"
# Create xaxis labels.
df['xaxis'] = df.apply(create_labels, axis=1)
# Create the graph.
data = []
layout = {'title': 'Combined X-Axis Labeling'}
data.append({'x': df['xaxis'],
'y': df['memused']})
layout['xaxis'] = {'title': '(Inference): Cumulative Time (ms)',
'type': 'category',
'nticks': df.shape[0] // 3500,
'tickangle': 45}
layout['yaxis'] = {'title': 'Memory Used (MB)'}
fig = {'data': data, 'layout': layout}
plot(fig, filename='/path/to/graph.html')