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')

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

The corresponding chart have these long lines, which i would line to suppress

Решением является добавление 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)
without resample with resample
no dates with NaN values dates with NaN values added

Если сравнить два выведенных 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 имеет другое поведение.

Вернуться на верх