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