#python #pandas #plotly #plotly.graph-objects
Вопрос:
В моем практическом обучении, которое я сейчас прохожу, есть скрипт python, который считывает файл CSV и отображает графики по выбранным столбцам этого файла. Однако выбор заголовков жестко запрограммирован, поэтому, если кто-то хочет использовать скрипт, он должен манипулировать кодом. Моя задача — сделать все это динамическим, например, пользователь скрипта может выбрать любое количество столбцов с помощью console ( argparse
), и скрипт автоматически создает трассировки, создает макет, добавляет оба к рисунку и экспортирует его в HTML-файл.
Мне удалось выполнить все это, за исключением части макета. В текущем (жестко закодированном) состоянии скрипта эти аргументы передаются graph_objects.Layout
функции:
layout = go.Layout(title=inFile,
plot_bgcolor='rgb(230, 230,230)', showlegend=True,
yaxis=dict(
title=df.columns[y1graph] # Note: 'ygraph' contains the index of the column
),
yaxis2=dict(
title=df.columns[y2graph],
side='right',
overlaying='y'
),
yaxis3=dict(
title=df.columns[y3graph],
side='right',
overlaying='y'
)
)
К сожалению, я не нашел способа сделать все это динамичным, чтобы аргументы «yaxis» добавлялись в соответствии с количеством выбранных столбцов. Я также не нашел способа добавлять заголовки к графикам, заставлять их накладываться друг на друга и помещать их в правую сторону так же, как go.Layout
это делается. Конечно, есть способ добавлять заголовки с помощью plotly express, но он как бы не делает то же самое для меня в отношении аргументов overlaying
and side
.
Есть идеи?
Пожалуйста, обратите внимание: это мой самый первый вопрос здесь, в stackoverflow, поэтому, если я сделал что-то не так, пожалуйста, посоветуйте! Кроме того, если я пропустил важную информацию, пожалуйста, дайте мне знать.
Комментарии:
1. Ваш вопрос может быть закрыт по нескольким причинам. Вам не хватает полного фрагмента и данных для воссоздания вашей проблемы, и вы задаете несколько вопросов в одном сообщении. Итак, несколько разъяснений будут в порядке. Во-первых, это график, который вы построили
make_subplots
?2. ХОРОШО, я сделаю все возможное, чтобы все прояснить. Спасибо за ваш совет! Исходный скрипт создается с использованием plotly.graph_objects. К сожалению, я не могу поделиться CSV из-за соображений защиты данных, и я спрошу официальных лиц, разрешено ли мне делиться всем сценарием. Однако способ его работы очень прост: сначала создаются, например, три переменные трассировки, которые назначаются вызову go.Scatter. Затем макет создается так, как я показал в своем исходном сообщении. Затем фигура создается с помощью go. Рисунок, со всеми трассировками, переданными как данные вместе с макетом.
3. Я опубликую весь код как можно скорее.
4. Разве Роб Рэймонд не нашел решение вашего вопроса?
Ответ №1:
- имитировать CSV, фрейм данных с 20 столбцами
- имитировать выбор пользователем столбцов для построения графика (произвольная выборка 4 столбцов из 20)
- постройте фигуру, назначив разные оси yaxis для каждой трассировки
- наконец, согласно вопросу, динамически настраивайте оси y
import numpy as np
import plotly.express as px
import pandas as pd
# simulate a CSV, 20 columns...
df = pd.DataFrame(
{
chr(ord("A") i): np.random.uniform(miny, miny 200, 30)
for i, miny in zip(range(20), np.random.randint(30, 3000, 20))
}
)
# simulate user passing columns to plot...
cols = pd.Series(df.columns).sample(4).tolist()
# build figure with each trace using it's own yaxis
fig = px.line(df, y=cols).for_each_trace(
lambda t: t.update(yaxis=f"y{cols.index(t.name) 1 if cols.index(t.name)>0 else ''}")
).update_layout(yaxis={"title":cols[0]})
# dynamically update yaxes...
fig.update_layout(
{
t.yaxis.replace("y", "yaxis"): {
"title": t.name,
"overlaying": "y",
"side": "right",
"position":1-(i/15)
}
for i,t in enumerate(fig.data)
if t.yaxis != "y"
}
).update_layout(xaxis={"domain":[0,1-(len(cols)*.05)]}) # give some space for additional yaxes