Plotly: Как установить значения для основных тиков / линий сетки для оси X? - PullRequest
1 голос
/ 14 марта 2019

Справочная информация:

Этот вопрос связан, но не идентичен, с График: Как получить значения для основных тиков и линий сетки? . Аналогичный вопрос также задавался, но не был дан ответ для matplotlib здесь: Как показать основные тики в качестве первого дня каждого месяца и второстепенные тики в качестве каждого дня?


Plotly - это фантастика , и, пожалуй, единственное, что меня беспокоит, - это автоматический выбор галочек / линий сетки и меток, выбранных для оси x, как на этом графике:

Сюжет 1:

enter image description here

Я думаю, что естественным показом здесь является первого числа каждого месяца (в зависимости от периода курса). Или, может быть, просто сокращенное название месяца, например 'Jan' на каждом тике. Я осознаю как технические, так и даже визуальные проблемы из-за того, что все месяцы не имеют одинаковую продолжительность. Но кто-нибудь знает, как это сделать?

Воспроизводимый фрагмент:

import plotly
import cufflinks as cf
from plotly.offline import download_plotlyjs, init_notebook_mode, plot, iplot
import pandas as pd
import numpy as np
from IPython.display import HTML
from IPython.core.display import display, HTML
import copy

# setup
init_notebook_mode(connected=True)
np.random.seed(123)
cf.set_config_file(theme='pearl')

# Random data using cufflinks
df = cf.datagen.lines()
#df = df['UUN.XY']

fig = df.iplot(asFigure=True, kind='scatter',
               xTitle='Dates',yTitle='Returns',title='Returns')

iplot(fig)

1 Ответ

0 голосов
/ 11 апреля 2019

Решение:

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

Step1:

Редактировать fig['data'][series]['x'] для каждой серии в fig['data'].

Шаг 2:

установить тикмод и текст в:

go.Layout(xaxis = go.layout.XAxis(tickvals = [some_values]
                                  ticktext = [other_values])
          )

Результат:

enter image description here

Полный код для ноутбука Jupyter:

# imports
import plotly
import cufflinks as cf
from plotly.offline import download_plotlyjs, init_notebook_mode, plot, iplot
import pandas as pd
import numpy as np
from IPython.display import HTML
from IPython.core.display import display, HTML
import copy
import plotly.graph_objs as go

# setup
init_notebook_mode(connected=True)
np.random.seed(123)
cf.set_config_file(theme='pearl')
#%qtconsole --style vim

# Random data using cufflinks
df = cf.datagen.lines()

# create figure setup
fig = df.iplot(asFigure=True, kind='scatter',
               xTitle='Dates',yTitle='Returns',title='Returns')

# create df1 to mess around with while
# keeping the source intact in df
df1 = df.copy(deep = True)
df1['idx'] = range(0, len(df))

# time variable operations and formatting
df1['yr'] = df1.index.year
df1['mth'] = df1.index.month_name()

# function to replace month name with
# abbreviated month name AND year
# if the month is january
def mthFormat(month):
    dDict = {'January':'jan','February':'feb', 'March':'mar',
             'April':'apr', 'May':'may','June':'jun', 'July':'jul',
             'August':'aug','September':'sep', 'October':'oct',
             'November':'nov', 'December':'dec'}
    mth = dDict[month]
    return(mth)

# replace month name with abbreviated month name
df1['mth'] = [mthFormat(m) for m in df1['mth']]


# remove adjacent duplicates for year and month
df1['yr'][df1['yr'].shift() == df1['yr']] = ''
df1['mth'][df1['mth'].shift() == df1['mth']] = ''

# select and format values to be displayed
df1['idx'][df1['mth']!='']
df1['display'] = df1['idx'][df1['mth']!='']
display = df1['display'].dropna()
displayVal = display.values.astype('int')
df_display = df1.iloc[displayVal]
df_display['display'] = df_display['display'].astype('int')
df_display['yrmth'] = df_display['mth'] + '<br>' + df_display['yr'].astype(str)

# set properties for each trace
for ser in range(0,len(fig['data'])):

    fig['data'][ser]['x'] = df1['idx'].values.tolist()
    fig['data'][ser]['text'] = df1['mth'].values.tolist()
    fig['data'][ser]['hoverinfo']='all'

# layout for entire figure
f2Data = fig['data']
f2Layout = go.Layout(
    xaxis = go.layout.XAxis(
        tickmode = 'array',
        tickvals = df_display['display'].values.tolist(),
        ticktext = df_display['yrmth'].values.tolist(),
        zeroline = False)#,
)

# plot figure with specified major ticks and gridlines
fig2 = go.Figure(data=f2Data, layout=f2Layout)
iplot(fig2)

Некоторые важные детали:


1.Гибкость и ограничения с iplot():

Этот подход с iplot() и редактированием всех этих настроек немного неуклюж, но он очень гибок в отношении количества столбцов / переменных в наборе данных,и, возможно, предпочтительнее построить каждую трассу вручную, например trace1 = go.Scatter() для каждого столбца в df.

2.Почему вы должны редактировать каждую серию / трассу?

Если вы попытаетесь пропустить среднюю часть с помощью

for ser in range(0,len(fig['data'])):

    fig['data'][ser]['x'] = df1['idx'].values.tolist()
    fig['data'][ser]['text'] = df1['mth'].values.tolist()
    fig['data'][ser]['hoverinfo']='all'

и попытаетесь установить tickvals и ticktext напрямуюна весь график это не повлияет:

enter image description here

Я думаю, что это немного странно, но я думаю, что это вызвано некоторыми базовыми настройками, инициированнымиiplot().

3.Одной вещи по-прежнему не хватает:

Для того, чтобы эта установка работала, структура ticvals и ticktext равна [0, 31, 59, 90] и ['jan<br>2015', 'feb<br>', 'mar<br>', 'apr<br>'] соответственно.Это приводит к тому, что в ховерстексте линии xaxis отображается положение данных, где ticvals и ticktext пусты:

enter image description here

Любые предложения по улучшениювсе это высоко ценится.Лучшее решение, чем мое, мгновенно получит Принятый ответ статус!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...