Bokeh Lasso selection with callback

I use lasso seletion to update my histogram from a scatter plot. I checked my source data and update function, but keep receiving error message on indexes. I can also post my code if needed.

Thank you and really appreciate for all the helps.

@appp We definitely need a Minimal Reproducible Example in order to investigate and say anything concrete.

This is my scatter plot

scatter = p.scatter(x='Dates', y='trip_duration', size='NumOfPass',line_color=None,fill_color='Color',source = source_scatter, legend='Vendor')

This is the histogram

x = df_scatterplot.trip_duration
hhist, hedges = np.histogram(x, bins=20)

hzeros = np.zeros(len(hedges)-1)
hmax = max(hhist)*1.1

LINE_ARGS1 = dict(color="#ffbdbd", line_color=None)
LINE_ARGS2 = dict(color="#d9f5d9", line_color=None)

ph = figure(title="Histogram", tools='', background_fill_color="#fafafa", plot_width=1500, plot_height=200, x_range=p.y_range, y_range=(0, hmax))
ph.xgrid.grid_line_color = None
ph.yaxis.major_label_orientation = np.pi/4

ph.quad(top=hhist, bottom=0, left=hedges[:-1], right=hedges[1:], color="white", line_color="#3A5785")
ph.y_range.start = 0
ph.yaxis.axis_label = "Number of Trips"
ph.xaxis.axis_label = "Trip Duration"
hh1 = ph.quad(top=hzeros, bottom=0, left=hedges[:-1], right=hedges[1:], alpha=0.5,**LINE_ARGS1)
hh2 = ph.quad(top=hzeros, bottom=0, left=hedges[:-1], right=hedges[1:], alpha=0.5,**LINE_ARGS2)

def update(attr, old, new):
    nds = new  # index of the data that are selected
    if len(nds) == 0 or len(nds) == len(x):
        hhist1, hhist2 = hzeros, hzeros
    else:
        neg_nds = np.ones_like(x, dtype=np.bool)
        neg_nds[nds] = False
        hhist1, _ = np.histogram(x[nds], bins=hedges)
        hhist2, _ = np.histogram(x[neg_nds], bins=hedges)

    hh1.data_source.data['top'] = hhist1
    hh2.data_source.data['top'] = -hhist2

# Bind the update function to lasso tool and data
scatter.data_source.selected.on_change('indices', update)

I keep having error message on the indexes of callback function while run on bokeh serve --show

@appp that is not an MRE because it is not complete. It needs to be something someone could copy and paste into a file, and run to investigate. Also whenever there is an error in question, it is always advised to actually provide the exact error message.

Please let me know if this help to clearify. Thank you.

And the complete codes are below

import pandas as pd
import numpy as np
from bokeh.io import output_file, show, save,curdoc, output_notebook
from bokeh.plotting import figure
from bokeh.models import ColumnDataSource, HoverTool,FactorRange, NumeralTickFormatter,HBar, DatetimeTickFormatter
from bokeh.models.widgets import Select
#from bokeh.layouts import column, row, gridplot
import bokeh.palettes as bp # uncomment it if you need special colors that are pre-defined
import datetime as dt
from math import pi
from bokeh.layouts import gridplot,row,column
from bokeh.models import BoxSelectTool, LassoSelectTool



df = pd.read_csv('data.csv')
np.random.seed(10)
remove_n = 1455000
drop_indices = np.random.choice(df.index, remove_n, replace=False)
df = df.drop(drop_indices)

df = df.drop(df[df.trip_duration > 2000].index)

df['pickup_datetime'] = pd.to_datetime(df['pickup_datetime'])
df['dates'] = df['pickup_datetime'].apply(lambda x: x.date())

color = list()
for i in range(len(df.index)):
    color.append("#A9A9A9")

df['color'] = color
colors =  ['#FF0000','#32CD32']
#Assign colors according to vendor_id
for idx in df.index:
    if df.at[idx,'vendor_id'] == 1:
        df.at[idx,'color'] = colors[0]
    else:
        df.at[idx,'color'] = colors[1]

df['vendor_id'] = df['vendor_id'].replace(to_replace = [1,2],value =["vendor_1","vendor_2"])

df_scatterplot = df.sort_values(by=['dates'])
df_scatterplot = df_scatterplot[['trip_duration','dates', 'vendor_id', 'color', 'passenger_count']]

df_scatterplot['dates'] = df_scatterplot['dates'].apply(lambda x: x.strftime("%Y-%m-%d"))

data = {'Vendor': df_scatterplot.vendor_id.tolist(),
            'NumOfPass': df_scatterplot.passenger_count.tolist(),
            'trip_duration': df_scatterplot.trip_duration.tolist(),
            'Dates' : df_scatterplot.dates.tolist(),
            'Color' : df_scatterplot.color.tolist()
    }
source_scatter = ColumnDataSource(data)

x_Range = df_scatterplot.dates.unique().tolist()
TOOLS="lasso_select, box_select, reset"

p = figure(tools=TOOLS, plot_width=3000, plot_height=900,
           toolbar_location="above",x_range = x_Range,
           title="NYC Taxi Traffic")

p.yaxis.axis_label = "Trip Duration (seconds)"
p.xaxis.axis_label = "Dates"
p.xaxis.major_label_orientation = pi/4
p.xaxis.major_label_text_font_size = '8px'
p.xgrid.grid_line_color = None
p.ygrid.grid_line_color = None
p.sizing_mode = "stretch_both"
p.select(LassoSelectTool).select_every_mousemove = False
p.select(BoxSelectTool).select_every_mousemove = False

from bokeh.models import LegendItem, Legend

hover = HoverTool(tooltips =
    [('Dates' , '@Dates'),
     ('Trip Duration' , '@trip_duration'),
     ('vendor_id', '@Vendor'),
    ('Number of passengers' , '@NumOfPass'),
    ])

p.add_tools(hover)

scatter = p.scatter(x='Dates', y='trip_duration', size='NumOfPass',line_color=None,fill_color='Color',source = source_scatter, legend='Vendor')

x = df_scatterplot.trip_duration
hhist, hedges = np.histogram(x, bins=20)

#vendor1_trip = df_scatterplot.loc[df_scatterplot['vendor_id'].str.match('vendor_1'),['trip_duration']]
#vendor2_trip = df_scatterplot.loc[df_scatterplot['vendor_id'].str.match('vendor_2'),['trip_duration']]

#hhist_vendor1, hedges_vendor1 = np.histogram(vendor1_trip, bins=20)
#hhist_vendor2, hedges_vendor2 = np.histogram(vendor2_trip, bins=20)

hzeros = np.zeros(len(hedges)-1)
hmax = max(hhist)*1.1
LINE_ARGS1 = dict(color="#ffbdbd", line_color=None)
LINE_ARGS2 = dict(color="#d9f5d9", line_color=None)

ph = figure(title="Histogram", tools='', background_fill_color="#fafafa", plot_width=1500, plot_height=200, x_range=p.y_range, y_range=(0, hmax))
ph.xgrid.grid_line_color = None
ph.yaxis.major_label_orientation = np.pi/4

ph.quad(top=hhist, bottom=0, left=hedges[:-1], right=hedges[1:], color="white", line_color="#3A5785")
ph.y_range.start = 0
ph.yaxis.axis_label = "Number of Trips"
ph.xaxis.axis_label = "Trip Duration"

hh1 = ph.quad(top=hzeros, bottom=0, left=hedges[:-1], right=hedges[1:], alpha=0.5,**LINE_ARGS1)
hh2 = ph.quad(top=hzeros, bottom=0, left=hedges[:-1], right=hedges[1:], alpha=0.5,**LINE_ARGS2)

def update(attr, old, new):
    nds = new  # index of the data that are selected
    if len(nds) == 0 or len(nds) == len(x):
        hhist1, hhist2 = hzeros, hzeros
    else:
        neg_nds = np.ones_like(x, dtype=np.bool)
        neg_nds[nds] = False
        hhist1, _ = np.histogram(x[nds], bins=hedges)
        hhist2, _ = np.histogram(x[neg_nds], bins=hedges)

    hh1.data_source.data['top'] = hhist1
    hh2.data_source.data['top'] = -hhist2

scatter.data_source.selected.on_change('indices', update)

layout = column(column(p, ph),width=100, height=100,sizing_mode='scale_both')
curdoc().add_root(layout)

When I copy and paste your code in to a file and try to run in it I immediately get an error from pandas:

bk-240 ❯ bokeh serve --show foo.py
2022-04-28 11:03:17,146 Starting Bokeh server version 2.4.2 (running on Tornado 6.1)
2022-04-28 11:03:17,149 User authentication hooks NOT provided (default user enabled)
2022-04-28 11:03:17,153 Bokeh app running at: http://localhost:5006/foo
2022-04-28 11:03:17,153 Starting Bokeh server with process id: 93561
2022-04-28 11:03:17,406 Error running application handler <bokeh.application.handlers.script.ScriptHandler object at 0x7fdc799f6580>: Cannot take a larger sample than population when 'replace=False'
File 'mtrand.pyx', line 959, in numpy.random.mtrand.RandomState.choice:
 Traceback (most recent call last):
  File "/Users/bryan/anaconda/envs/bk-240/lib/python3.9/site-packages/bokeh/application/handlers/code_runner.py", line 231, in run
    exec(self._code, module.__dict__)
  File "/Users/bryan/tmp/foo.py", line 19, in <module>
    drop_indices = np.random.choice(df.index, remove_n, replace=False)
  File "mtrand.pyx", line 959, in numpy.random.mtrand.RandomState.choice
ValueError: Cannot take a larger sample than population when 'replace=False'

Also another ask: On any help forum, please always paste actual text for error messages and code, rather than images of such (images are not accessible to anyone who might need to use assistive technologies to read the page).

Thank you for the note. The below is the error message that I receive. I have been able to created the scatter and histogram ok. But keep having error massage with lasson selection.

(base) C:\Users\OS\Desktop\Visualization concept\Excercise\Ex 3>bokeh serve --show ex3.ipynb
2022-04-28 19:40:41,290 Starting Bokeh server version 2.4.1 (running on Tornado 6.1)
2022-04-28 19:40:41,293 User authentication hooks NOT provided (default user enabled)
2022-04-28 19:40:41,301 Bokeh app running at: http://localhost:5006/ex3
2022-04-28 19:40:41,301 Starting Bokeh server with process id: 19856
BokehDeprecationWarning: 'legend' keyword is deprecated, use explicit 'legend_label', 'legend_field', or 'legend_group' keywords instead
2022-04-28 19:40:46,889 C:\Users\OS\Desktop\Visualization concept\Excercise\Ex 3\ex3.ipynb: call to output_file() ignored when running notebooks with the 'bokeh' command.
2022-04-28 19:40:46,889 C:\Users\OS\Desktop\Visualization concept\Excercise\Ex 3\ex3.ipynb: call to save() ignored when running notebooks with the 'bokeh' command.
2022-04-28 19:40:47,352 WebSocket connection opened
2022-04-28 19:40:47,353 ServerConnection created
2022-04-28 19:41:23,228 error handling message
 message: Message 'PATCH-DOC' content: {'events': [{'kind': 'ModelChanged', 'model': {'id': '1064'}, 'attr': 'indices', 'new': [304, 305, 306, 307, 309, 310, 311, 315, 317, 319, 321, 322, 329, 330, 332, 333, 336, 344, 345, 348, 349, 352, 354, 355, 360, 361, 362, 366, 368, 370, 373, 374, 375, 377, 379, 380, 381, 383, 385, 386, 388, 389, 392, 397, 402, 403, 407, 410, 414, 415, 416, 421, 423, 427, 430, 431, 434, 436, 439, 444, 448, 450, 453, 457, 466, 472, 473, 474, 475, 476, 479, 482, 483, 487, 488, 490, 491, 492, 493, 494, 496, 497, 498, 504, 506, 507, 508, 510, 511, 512, 515, 518, 520, 521, 524, 525, 526, 527, 528, 530, 531, 532, 533, 534, 538, 544, 545, 546, 547, 552, 555, 556, 558, 562, 563, 564, 565, 569, 570, 571, 572, 573, 576, 578, 580, 581, 583, 584, 590, 591, 592, 593, 594, 595, 596, 597, 598, 602, 603, 605, 606, 609, 610, 611, 612, 613, 615, 618, 619, 620, 621, 624, 625, 626, 627, 628, 630, 631, 633, 640, 644, 645, 647, 649, 650, 652, 654, 655, 657, 659, 660, 661, 663, 665, 666, 670, 671, 673, 674, 675, 677, 678, 679, 680, 681, 682, 684, 685, 688, 689, 691, 692, 693, 696, 697, 698, 700, 703, 705, 707, 710, 713, 715, 718, 720, 722, 726, 727, 728, 730, 734, 735, 737, 738, 739, 740, 741, 742, 745, 748, 753, 755, 756, 757, 759, 764, 767, 768, 769, 771, 772, 774, 775, 778, 780, 783, 784, 785, 787, 788, 790, 792, 794, 796, 797, 799, 803, 805, 806, 807, 808, 814, 815, 817, 818, 819, 820, 823, 824, 825, 826, 828, 831, 835, 836, 837, 838, 839, 840, 841, 843, 844, 845, 846, 848, 850, 851, 852, 856, 858, 861, 865, 868, 873, 874, 875, 880, 881, 884, 886, 887, 888, 889, 890, 894, 897, 898, 903, 904, 908, 909, 910, 917, 918, 919, 923, 925, 926, 929, 930, 931, 932, 933, 935, 940, 942, 943, 944, 945, 949, 950, 951, 952, 953, 954, 955, 956, 957, 960, 961, 962, 967, 968, 969, 971, 972, 973, 974, 975, 976, 977, 979, 980, 981, 982, 983, 985, 987, 988, 990, 993, 994, 995, 996, 997, 1001, 1003, 1005, 1006, 1008, 1011, 1013, 1015, 1017, 1018, 1019, 1020, 1022, 1025, 1027, 1029, 1030, 1036, 1037, 1042, 1044, 1046, 1049, 1050, 1051, 1054, 1055, 1056, 1058, 1061, 1062, 1063, 1065, 1068, 1069, 1071, 1072, 1075, 1076, 1077, 1081, 1082, 1084, 1088, 1089, 1090, 1091, 1093, 1096, 1097, 1098, 1099, 1101, 1104, 1111, 1112, 1113, 1118, 1121, 1124, 1125, 1128, 1129, 1130, 1131, 1134, 1135, 1136, 1137, 1138, 1147, 1148, 1151, 1153, 1154, 1156, 1163, 1167, 1169, 1173, 1175, 1176, 1177, 1178, 1181, 1182, 1183, 1184, 1185, 1186, 1193, 1195, 1196, 1197, 1198, 1201, 1204, 1206, 1210, 1211, 1213, 1214, 1215, 1216, 1219, 1223, 1225, 1226, 1228, 1229, 1233, 1234, 1238, 1240, 1244, 1245, 1247, 1252, 1254, 1255, 1257, 1259, 1264, 1265, 1266, 1272, 1274, 1275, 1276, 1277, 1280, 1281, 1283, 1286, 1288, 1290, 1291, 1293, 1295, 1296, 1298, 1306, 1307, 1309, 1310, 1311, 1313, 1314, 1316, 1318, 1319, 1320, 1323, 1330, 1331, 1334, 1335, 1336, 1337, 1341, 1348, 1349, 1350, 1355, 1358, 1362, 1366, 1367, 1371, 1372, 1373, 1374, 1377, 1380, 1381, 1382, 1383, 1385, 1389, 1390, 1394, 1395, 1399, 1403, 1405, 1406, 1407, 1410, 1411, 1413, 1415, 1420, 1421, 1422, 1424, 1427, 1428, 1431, 1432, 1436, 1438, 1439, 1451, 1454, 1456, 1457, 1458, 1459, 1464, 1465, 1468, 1479, 1482, 1483, 1493, 1501, 1502, 1504, 1507, 1508, 1518, 1519, 1522, 1525, 1526, 1531, 1535, 1536, 1537, 1542, 1544, 1545, 1551, 1552, 1556, 1557, 1562, 1566, 1567, 1568, 1573, 1576, 1584, 1586, 1609, 1618]}], 'references': []}
 error: KeyError('[304, 305, 306, 307, 309, 310, 311, 315, 317, 319, 321, 322, 329, 330, 332, 333, 336, 344, 345, 348, 349, 352, 354, 355, 360, 361, 362, 366, 368, 370, 373, 374, 375, 377, 379, 380, 381, 383, 385, 386, 388, 389, 392, 397, 402, 403, 407, 410, 414, 415, 416, 421, 423, 427, 430, 431, 434, 436, 439, 444, 448, 450, 453, 457, 466, 472, 473, 474, 475, 476, 479, 482, 483, 487, 488, 490, 491, 492, 493, 494, 496, 497, 498, 504, 506, 507, 508, 510, 511, 512, 515, 518, 520, 521, 524, 525, 526, 527, 528, 530, 531, 532, 533, 534, 538, 544, 545, 546, 547, 552, 555, 556, 558, 562, 563, 564, 565, 569, 570, 571, 572, 573, 576, 578, 580, 581, 583, 584, 590, 591, 592, 593, 594, 595, 596, 597, 598, 602, 603, 605, 606, 609, 610, 611, 612, 613, 615, 618, 619, 620, 621, 624, 625, 626, 627, 628, 630, 631, 633, 640, 644, 645, 647, 649, 650, 652, 654, 655, 657, 659, 660, 661, 663, 665, 666, 670, 671, 673, 674, 675, 677, 678, 679, 680, 681, 682, 684, 685, 688, 689, 691, 692, 693, 696, 697, 698, 700, 703, 705, 707, 710, 713, 715, 718, 720, 722, 726, 727, 728, 730, 734, 735, 737, 738, 739, 740, 741, 742, 745, 748, 753, 755, 756, 757, 759, 764, 767, 768, 769, 771, 772, 774, 775, 778, 780, 783, 784, 785, 787, 788, 790, 792, 794, 796, 797, 799, 803, 805, 806, 807, 814, 815, 817, 818, 819, 820, 823, 824, 825, 826, 828, 831, 835, 836, 837, 838, 839, 840, 841, 843, 844, 845, 846, 848, 850, 851, 852, 856, 858, 861, 865, 868, 873, 874, 875, 880, 881, 884, 886, 887, 888, 889, 890, 894, 897, 898, 903, 904, 908, 909, 910, 917, 918, 919, 923, 925, 926, 929, 930, 931, 932, 933, 935, 940, 942, 943, 944, 945, 949, 950, 951, 952, 953, 954, 955, 956, 957, 960, 961, 962, 967, 968, 969, 971, 972, 973, 974, 975, 976, 977, 979, 980, 981, 982, 983, 985, 987, 988, 990, 993, 994, 995, 996, 997, 1001, 1003, 1005, 1006, 1008, 1011, 1013, 1015, 1017, 1018, 1019, 1020, 1022, 1025, 1027, 1029, 1030, 1036, 1037, 1042, 1044, 1046, 1049, 1050, 1051, 1054, 1055, 1056, 1058, 1061, 1062, 1063, 1065, 1068, 1069, 1071, 1072, 1075, 1076, 1077, 1081, 1082, 1084, 1088, 1089, 1090, 1091, 1093, 1096, 1097, 1098, 1099, 1101, 1104, 1111, 1112, 1113, 1118, 1121, 1124, 1125, 1128, 1129, 1130, 1131, 1134, 1135, 1136, 1137, 1138, 1147, 1148, 1151, 1153, 1154, 1156, 1163, 1167, 1169, 1173, 1175, 1176, 1177, 1178, 1181, 1182, 1183, 1184, 1185, 1186, 1193, 1195, 1196, 1197, 1198, 1201, 1204, 1206, 1210, 1211, 1213, 1214, 1215, 1216, 1219, 1223, 1225, 1226, 1228, 1229, 1233, 1234, 1238, 1240, 1244, 1245, 1247, 1252, 1254, 1255, 1257, 1259, 1264, 1265, 1266, 1272, 1274, 1275, 1276, 1277, 1280, 1281, 1283, 1286, 1288, 1290, 1291, 1293, 1295, 1296, 1298, 1306, 1307, 1309, 1310, 1311, 1313, 1314, 1316, 1318, 1319, 1320, 1323, 1330, 1331, 1334, 1335, 1336, 1337, 1341, 1348, 1349, 1350, 1355, 1358, 1362, 1366, 1367, 1371, 1372, 1373, 1374, 1377, 1380, 1381, 1382, 1383, 1385, 1389, 1390, 1394, 1395, 1399, 1403, 1405, 1406, 1407, 1410, 1411, 1413, 1415, 1420, 1421, 1422, 1424, 1427, 1428, 1431, 1432, 1436, 1438, 1439, 1451, 1454, 1456, 1457, 1458, 1459, 1464, 1465, 1468, 1479, 1482, 1483, 1493, 1501, 1502, 1504, 1507, 1508, 1518, 1519, 1522, 1525, 1526, 1531, 1535, 1536, 1537, 1542, 1544, 1545, 1551, 1552, 1556, 1557, 1562, 1566, 1567, 1568, 1573, 1576, 1584, 1586, 1609, 1618] not in index')
Traceback (most recent call last):
  File "C:\Users\OS\anaconda3\lib\site-packages\bokeh\server\protocol_handler.py", line 97, in handle
    work = await handler(message, connection)
  File "C:\Users\OS\anaconda3\lib\site-packages\bokeh\server\session.py", line 93, in _needs_document_lock_wrapper
    result = func(self, *args, **kwargs)
  File "C:\Users\OS\anaconda3\lib\site-packages\bokeh\server\session.py", line 287, in _handle_patch
    message.apply_to_document(self.document, self)
  File "C:\Users\OS\anaconda3\lib\site-packages\bokeh\protocol\messages\patch_doc.py", line 115, in apply_to_document
    invoke_with_curdoc(doc, lambda: doc.apply_json_patch(self.content, setter))
  File "C:\Users\OS\anaconda3\lib\site-packages\bokeh\document\callbacks.py", line 408, in invoke_with_curdoc
    return f()
  File "C:\Users\OS\anaconda3\lib\site-packages\bokeh\protocol\messages\patch_doc.py", line 115, in <lambda>
    invoke_with_curdoc(doc, lambda: doc.apply_json_patch(self.content, setter))
  File "C:\Users\OS\anaconda3\lib\site-packages\bokeh\document\document.py", line 391, in apply_json_patch
    DocumentPatchedEvent.handle_json(self, event_json, references, setter)
  File "C:\Users\OS\anaconda3\lib\site-packages\bokeh\document\events.py", line 259, in handle_json
    handler(doc, event_json, references, setter)
  File "C:\Users\OS\anaconda3\lib\site-packages\bokeh\document\events.py", line 467, in _handle_json
    patched_obj.set_from_json(attr, value, models=references, setter=setter)
  File "C:\Users\OS\anaconda3\lib\site-packages\bokeh\core\has_props.py", line 384, in set_from_json
    descriptor.set_from_json(self, json, models=models, setter=setter)
  File "C:\Users\OS\anaconda3\lib\site-packages\bokeh\core\property\descriptors.py", line 378, in set_from_json
    self._set(obj, old, value, setter=setter)
  File "C:\Users\OS\anaconda3\lib\site-packages\bokeh\core\property\descriptors.py", line 559, in _set
    self._trigger(obj, old, value, hint=hint, setter=setter)
  File "C:\Users\OS\anaconda3\lib\site-packages\bokeh\core\property\descriptors.py", line 637, in _trigger
    obj.trigger(self.name, old, value, hint, setter)
  File "C:\Users\OS\anaconda3\lib\site-packages\bokeh\model\model.py", line 567, in trigger
    super().trigger(descriptor.name, old, new, hint=hint, setter=setter)
  File "C:\Users\OS\anaconda3\lib\site-packages\bokeh\util\callback_manager.py", line 194, in trigger
    self.document.callbacks.notify_change(cast(Model, self), attr, old, new, hint, setter, invoke)
  File "C:\Users\OS\anaconda3\lib\site-packages\bokeh\document\callbacks.py", line 236, in notify_change
    self.trigger_on_change(event)
  File "C:\Users\OS\anaconda3\lib\site-packages\bokeh\document\callbacks.py", line 373, in trigger_on_change
    invoke_with_curdoc(doc, event.callback_invoker)
  File "C:\Users\OS\anaconda3\lib\site-packages\bokeh\document\callbacks.py", line 408, in invoke_with_curdoc
    return f()
  File "C:\Users\OS\anaconda3\lib\site-packages\bokeh\util\callback_manager.py", line 191, in invoke
    callback(attr, old, new)
  File "C:\Users\OS\Desktop\Visualization concept\Excercise\Ex 3\ex3.ipynb", line 237, in update
    },
  File "C:\Users\OS\anaconda3\lib\site-packages\pandas\core\series.py", line 966, in __getitem__
    return self._get_with(key)
  File "C:\Users\OS\anaconda3\lib\site-packages\pandas\core\series.py", line 1001, in _get_with
    return self.loc[key]
  File "C:\Users\OS\anaconda3\lib\site-packages\pandas\core\indexing.py", line 931, in __getitem__
    return self._getitem_axis(maybe_callable, axis=axis)
  File "C:\Users\OS\anaconda3\lib\site-packages\pandas\core\indexing.py", line 1153, in _getitem_axis
    return self._getitem_iterable(key, axis=axis)
  File "C:\Users\OS\anaconda3\lib\site-packages\pandas\core\indexing.py", line 1093, in _getitem_iterable
    keyarr, indexer = self._get_listlike_indexer(key, axis)
  File "C:\Users\OS\anaconda3\lib\site-packages\pandas\core\indexing.py", line 1314, in _get_listlike_indexer
    self._validate_read_indexer(keyarr, indexer, axis)
  File "C:\Users\OS\anaconda3\lib\site-packages\pandas\core\indexing.py", line 1377, in _validate_read_indexer
    raise KeyError(f"{not_found} not in index")
KeyError: '[304, 305, 306, 307, 309, 310, 311, 315, 317, 319, 321, 322, 329, 330, 332, 333, 336, 344, 345, 348, 349, 352, 354, 355, 360, 361, 362, 366, 368, 370, 373, 374, 375, 377, 379, 380, 381, 383, 385, 386, 388, 389, 392, 397, 402, 403, 407, 410, 414, 415, 416, 421, 423, 427, 430, 431, 434, 436, 439, 444, 448, 450, 453, 457, 466, 472, 473, 474, 475, 476, 479, 482, 483, 487, 488, 490, 491, 492, 493, 494, 496, 497, 498, 504, 506, 507, 508, 510, 511, 512, 515, 518, 520, 521, 524, 525, 526, 527, 528, 530, 531, 532, 533, 534, 538, 544, 545, 546, 547, 552, 555, 556, 558, 562, 563, 564, 565, 569, 570, 571, 572, 573, 576, 578, 580, 581, 583, 584, 590, 591, 592, 593, 594, 595, 596, 597, 598, 602, 603, 605, 606, 609, 610, 611, 612, 613, 615, 618, 619, 620, 621, 624, 625, 626, 627, 628, 630, 631, 633, 640, 644, 645, 647, 649, 650, 652, 654, 655, 657, 659, 660, 661, 663, 665, 666, 670, 671, 673, 674, 675, 677, 678, 679, 680, 681, 682, 684, 685, 688, 689, 691, 692, 693, 696, 697, 698, 700, 703, 705, 707, 710, 713, 715, 718, 720, 722, 726, 727, 728, 730, 734, 735, 737, 738, 739, 740, 741, 742, 745, 748, 753, 755, 756, 757, 759, 764, 767, 768, 769, 771, 772, 774, 775, 778, 780, 783, 784, 785, 787, 788, 790, 792, 794, 796, 797, 799, 803, 805, 806, 807, 814, 815, 817, 818, 819, 820, 823, 824, 825, 826, 828, 831, 835, 836, 837, 838, 839, 840, 841, 843, 844, 845, 846, 848, 850, 851, 852, 856, 858, 861, 865, 868, 873, 874, 875, 880, 881, 884, 886, 887, 888, 889, 890, 894, 897, 898, 903, 904, 908, 909, 910, 917, 918, 919, 923, 925, 926, 929, 930, 931, 932, 933, 935, 940, 942, 943, 944, 945, 949, 950, 951, 952, 953, 954, 955, 956, 957, 960, 961, 962, 967, 968, 969, 971, 972, 973, 974, 975, 976, 977, 979, 980, 981, 982, 983, 985, 987, 988, 990, 993, 994, 995, 996, 997, 1001, 1003, 1005, 1006, 1008, 1011, 1013, 1015, 1017, 1018, 1019, 1020, 1022, 1025, 1027, 1029, 1030, 1036, 1037, 1042, 1044, 1046, 1049, 1050, 1051, 1054, 1055, 1056, 1058, 1061, 1062, 1063, 1065, 1068, 1069, 1071, 1072, 1075, 1076, 1077, 1081, 1082, 1084, 1088, 1089, 1090, 1091, 1093, 1096, 1097, 1098, 1099, 1101, 1104, 1111, 1112, 1113, 1118, 1121, 1124, 1125, 1128, 1129, 1130, 1131, 1134, 1135, 1136, 1137, 1138, 1147, 1148, 1151, 1153, 1154, 1156, 1163, 1167, 1169, 1173, 1175, 1176, 1177, 1178, 1181, 1182, 1183, 1184, 1185, 1186, 1193, 1195, 1196, 1197, 1198, 1201, 1204, 1206, 1210, 1211, 1213, 1214, 1215, 1216, 1219, 1223, 1225, 1226, 1228, 1229, 1233, 1234, 1238, 1240, 1244, 1245, 1247, 1252, 1254, 1255, 1257, 1259, 1264, 1265, 1266, 1272, 1274, 1275, 1276, 1277, 1280, 1281, 1283, 1286, 1288, 1290, 1291, 1293, 1295, 1296, 1298, 1306, 1307, 1309, 1310, 1311, 1313, 1314, 1316, 1318, 1319, 1320, 1323, 1330, 1331, 1334, 1335, 1336, 1337, 1341, 1348, 1349, 1350, 1355, 1358, 1362, 1366, 1367, 1371, 1372, 1373, 1374, 1377, 1380, 1381, 1382, 1383, 1385, 1389, 1390, 1394, 1395, 1399, 1403, 1405, 1406, 1407, 1410, 1411, 1413, 1415, 1420, 1421, 1422, 1424, 1427, 1428, 1431, 1432, 1436, 1438, 1439, 1451, 1454, 1456, 1457, 1458, 1459, 1464, 1465, 1468, 1479, 1482, 1483, 1493, 1501, 1502, 1504, 1507, 1508, 1518, 1519, 1522, 1525, 1526, 1531, 1535, 1536, 1537, 1542, 1544, 1545, 1551, 1552, 1556, 1557, 1562, 1566, 1567, 1568, 1573, 1576, 1584, 1586, 1609, 1618] not in index'

@appp Thanks for the error text, but I still cannot run your code. See different, earlier pandas error above. It’s failing right here at the start, before a page is even generated:

drop_indices = np.random.choice(df.index, remove_n, replace=False)