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

The solution is to add NaN to all dates without a valid value to your DataFrame, because the line renderer interpolates between given data points. If there is a NaN value, nothing is plotted. In your case one option is to add a simple frequency using pandas resample() function.

See the minimal example below:

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

If we compare the two printed DataFrames, you can see whats changed.

This is the DataFrame without the resample call.

            opening_price
datetime                 
2024-04-15              1
2024-04-16              1
2024-04-19             -1
2024-04-20             -1

And this the changed one.

            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

Keep in mind that the line call needs at least two consecutive data points to draw a line. A single point will be invisable using line. The circle renderer has a different behavior.

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