Bokeh, как удалить даты без соответствующих значений?
надеюсь, у вас все хорошо, я хотел бы отобразить график без длинных линий, которые соответствуют значениям, не имеющим соответствующей пары.
Вот функция, которая генерирует мой график, надеюсь, я вас не напугаю:
def get(self, request):
user=request.user
historical_me=FinancialInstrument.objects.all()
form = self.form_class(historical_me=historical_me)
retrive=HistoricalData.objects.all()
get_symbol=retrive.filter(instrument__symbol="BTUSD").order_by('datetime')
fields=get_symbol.values('datetime','opening_price','closing_price','min_price','max_price','volume')
df=pd.DataFrame.from_records(fields)
x_values = [key.datetime for key in get_symbol]
y_values = [float(key.opening_price) for key in get_symbol]
source = ColumnDataSource(data=dict(dater=x_values,pricer=y_values))
plot = figure(title="New title", width=780, height=400,
x_axis_label="Date", y_axis_label="Max Price", x_axis_type="datetime")
plot.line(x='dater',y='pricer', source=source,line_width=3)
unique_dates = HistoricalData.objects.order_by('datetime').values_list('datetime', flat=True).distinct()
plot.line(x='datetime', y='opening_price', source=source, line_width=3)
plot.toolbar.autohide = True
script, div = components(plot)
if user.is_authenticated:
return render(
request,
self.template_name,
{
'form':form,
'days_of_month': [i for i in range(1,32)],
'script':script,
'div':div,
})
return redirect('home')
Вот график, который он создает, мне нужен подход, чтобы подавить эти длинные линии, которые соответствуют датам, не имеющим соответствующего значения.
Решением является добавление NaN
ко всем датам без действительного значения DataFrame
, поскольку рендерер line
интерполирует между заданными точками данных. Если есть значение NaN
, то ничего не отображается. В вашем случае один из вариантов - добавить простую частоту с помощью функции pandas resample()
.
Смотрите минимальный пример ниже:
import pandas as pd
from bokeh.plotting import figure, show, output_notebook
output_notebook()
data = {
'datetime': ['2024-04-15', '2024-04-16', '2024-04-19', '2024-04-20'],
'opening_price': [1, 1, -1, -1],
}
df = pd.DataFrame(data)
df['datetime'] = pd.to_datetime(df['datetime'])
df.set_index('datetime', inplace=True)
# the one line which adds a frequency and to all not know dates the value `NaN`
df = df.resample('1D').mean()
p = figure(x_axis_type='datetime', x_axis_label='date', y_axis_label='change')
p.line(x='datetime', y='opening_price', source=df, line_width=3)
show(p)
Если сравнить два выведенных DataFrames, то можно увидеть, что изменилось.
Это кадр данных без вызова resample
.
opening_price
datetime
2024-04-15 1
2024-04-16 1
2024-04-19 -1
2024-04-20 -1
А это измененный.
opening_price
datetime
2024-04-15 1.0
2024-04-16 1.0
2024-04-17 NaN
2024-04-18 NaN
2024-04-19 -1.0
2024-04-20 -1.0
Помните, что вызов line
требует как минимум двух последовательных точек данных для построения линии. Одиночная точка будет невидимой при использовании line
. Рендерер circle
имеет другое поведение.