Skip to content

Instantly share code, notes, and snippets.

@mhhennig
Last active September 9, 2024 17:34
Show Gist options
  • Save mhhennig/03fbccce6251f453bf0c53332a94ad45 to your computer and use it in GitHub Desktop.
Save mhhennig/03fbccce6251f453bf0c53332a94ad45 to your computer and use it in GitHub Desktop.
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"/disk/scratch/mhennig/spikeinterface/HS2/testing/../herdingspikes/__init__.py 0.4.004+git.1a5d42e47ffc\n"
]
}
],
"source": [
"%load_ext autoreload\n",
"%autoreload 2\n",
"\n",
"import os, sys\n",
"sys.path.insert(0,\"../\")\n",
"sys.path.insert(0,\"../../spikeinterface_dev/src\")\n",
"\n",
"import spikeinterface.full as si\n",
"\n",
"from spikeinterface.sortingcomponents.peak_detection import detect_peaks, detect_peak_methods\n",
"from spikeinterface.sortingcomponents.peak_selection import select_peaks\n",
"from spikeinterface.sortingcomponents.peak_localization import localize_peaks, localize_peak_methods\n",
"from spikeinterface.sortingcomponents.motion import estimate_motion, InterpolateMotionRecording\n",
"from spikeinterface.core.node_pipeline import ExtractDenseWaveforms, run_node_pipeline\n",
"\n",
"import herdingspikes as hs\n",
"import numpy as np\n",
"from matplotlib import pyplot as plt\n",
"si.set_global_job_kwargs(n_jobs=-1, progress_bar=False, chunk_duration=\"1s\")\n",
"\n",
"import timeit\n",
"import pandas as pd\n",
"import seaborn as sns\n",
"\n",
"import time\n",
"\n",
"print(hs.__file__, hs.__version__)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Generate data"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"GENERATE_RECORDING = False\n",
"recording_name = 'simulated_neuropixels_recording'\n",
"times = {}"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"num_units=200\n",
"if GENERATE_RECORDING:\n",
" rec, rec_drift, gt_sorting = si.generate_drifting_recording(\n",
" num_units=num_units,\n",
" duration=600.,\n",
" sampling_frequency=30000.0,\n",
" generate_probe_kwargs = dict(\n",
" num_columns=4,\n",
" num_contact_per_column=[96] * 4,\n",
" xpitch=16,\n",
" ypitch=40,\n",
" y_shift_per_column=[20, 0, 20, 0],\n",
" contact_shapes=\"square\",\n",
" contact_shape_params={\"width\": 12},\n",
" ),\n",
" generate_templates_kwargs=dict(\n",
" ms_before=1.5,\n",
" ms_after=3.0,\n",
" mode=\"ellipsoid\",\n",
" unit_params=dict(\n",
" alpha=(150.0, 500.0),\n",
" spatial_decay=(10, 45),\n",
" ),\n",
" ),\n",
" generate_unit_locations_kwargs=dict(\n",
" margin_um=10.0,\n",
" minimum_z=6.0,\n",
" maximum_z=25.0,\n",
" minimum_distance=12.0,\n",
" max_iteration=100,\n",
" distance_strict=False,\n",
" ), \n",
" generate_sorting_kwargs=dict(\n",
" firing_rates=(0.1, 4.0),\n",
" refractory_period_ms=4.0\n",
" ),\n",
" generate_noise_kwargs=dict(\n",
" noise_levels=(5.0, 10.0),\n",
" spatial_decay=25.0\n",
" ),\n",
" seed=42\n",
" )\n",
" rec.save_to_folder(\n",
" recording_name, folder=recording_name, overwrite=True\n",
" )\n",
" rec"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## SpikeInterface Detect+COM"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"def run_node():\n",
" job_kwargs = {}\n",
" detect_kwargs = {}\n",
" select_kwargs={}\n",
" localize_peaks_kwargs={}\n",
" estimate_motion_kwargs={}\n",
" interpolate_motion_kwargs={}\n",
"\n",
" # maybe do this directly in the folder when not None, but might be slow on external storage\n",
" gather_mode = \"memory\"\n",
" # node detect\n",
" method = detect_kwargs.pop(\"method\", \"locally_exclusive\")\n",
" method_class = detect_peak_methods[method]\n",
" node0 = method_class(rec_in_mem, **detect_kwargs)\n",
"\n",
" node1 = ExtractDenseWaveforms(rec_in_mem, parents=[node0], ms_before=0.3, ms_after=1.8)\n",
"\n",
" # node detect + localize\n",
" method = localize_peaks_kwargs.pop(\"method\", \"center_of_mass\")\n",
" method_class = localize_peak_methods[method]\n",
" node2 = method_class(\n",
" rec_in_mem, parents=[node0, node1], return_output=True, **localize_peaks_kwargs\n",
" )\n",
" pipeline_nodes = [node0, node1, node2]\n",
"\n",
" peaks, peak_locations = run_node_pipeline(\n",
" rec_in_mem,\n",
" pipeline_nodes,\n",
" job_kwargs,\n",
" job_name=\"detect and localize\",\n",
" gather_mode=gather_mode,\n",
" gather_kwargs=None,\n",
" squeeze_output=False,\n",
" folder=None,\n",
" names=None,\n",
" )\n"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [],
"source": [
"if 'rec_in_mem' in globals():\n",
" del(rec_in_mem)\n",
"rec_in_mem = si.load_extractor(recording_name);\n",
"t0 = time.perf_counter()\n",
"run_node()\n",
"t1 = time.perf_counter()\n",
"\n",
"times['SI detect+COM'] = t1-t0"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Herdingspikes"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [],
"source": [
"parameters = {\n",
" \"chunk_size\": 32000,\n",
" \"lowpass\": True,\n",
" \"rescale\": True,\n",
" \"rescale_value\": -1280.0,\n",
" \"common_reference\": \"average\",\n",
" # \"common_reference\": \"median\",\n",
" \"spike_duration\": 1.0,\n",
" \"amp_avg_duration\": 0.4,\n",
" \"threshold\": 8.0,\n",
" \"min_avg_amp\": 1.0,\n",
" \"AHP_thr\": 0.0,\n",
" \"neighbor_radius\": 90.0,\n",
" \"inner_radius\": 70.0,\n",
" \"peak_jitter\": 0.25,\n",
" \"rise_duration\": 0.26,\n",
" \"decay_filtering\": False,\n",
" \"decay_ratio\": 1.0,\n",
" \"localize\": True,\n",
" \"save_shape\": True,\n",
" \"out_file\": \"HS2_detected\",\n",
" \"left_cutout_time\": 0.3,\n",
" \"right_cutout_time\": 1.8,\n",
" \"verbose\": False,\n",
" \"clustering_bandwidth\": 4.0,\n",
" \"clustering_alpha\": 4.5,\n",
" \"clustering_n_jobs\": -1,\n",
" \"clustering_bin_seeding\": True,\n",
" \"clustering_min_bin_freq\": 4,\n",
" \"clustering_subset\": None,\n",
" \"pca_ncomponents\": 2,\n",
" \"pca_whiten\": True,\n",
"}"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [],
"source": [
"if 'rec_in_mem' in globals():\n",
" del(rec_in_mem)\n",
"rec_in_mem = si.load_extractor(recording_name);\n",
"t0 = time.perf_counter()\n",
"det = hs.HSDetectionLightning(rec_in_mem, parameters)\n",
"det.DetectFromRaw()\n",
"t1 = time.perf_counter()\n",
"\n",
"times['herdingspikes detect'] = t1-t0"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Reading spikes from detection\n",
"Fitting dimensionality reduction using all spikes...\n",
"...projecting...\n",
"...done\n",
"Clustering...\n",
"Clustering 211677 spikes...\n",
"requested -1 cpus\n",
"using 8 cpus\n",
"number of seeds: 1912\n",
"seeds/job: 240\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"[Parallel(n_jobs=8)]: Using backend LokyBackend with 8 concurrent workers.\n",
"[Parallel(n_jobs=8)]: Done 3 out of 8 | elapsed: 3.1s remaining: 5.1s\n",
"[Parallel(n_jobs=8)]: Done 8 out of 8 | elapsed: 3.3s finished\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Number of estimated units: 190\n"
]
}
],
"source": [
"t0 = time.perf_counter()\n",
"Clusters = hs.HSClustering(det)\n",
"Clusters.ShapePCA()\n",
"Clusters.CombinedClustering(\n",
" alpha=parameters[\"clustering_alpha\"],\n",
" bandwidth=parameters[\"clustering_bandwidth\"],\n",
" bin_seeding=parameters[\"clustering_bin_seeding\"],\n",
" min_bin_freq=parameters[\"clustering_min_bin_freq\"],\n",
" cluster_subset=parameters[\"clustering_subset\"],\n",
" n_jobs=-1)\n",
"t1 = time.perf_counter()\n",
"times['herdingspikes sort'] = t1-t0\n",
"times['herdingspikes all'] = times['herdingspikes detect']+times['herdingspikes sort']"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Kilosort4"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/tmp/ipykernel_179427/2912753937.py:7: DeprecationWarning: `output_folder` is deprecated and will be removed in version 0.103.0 Please use folder instead\n",
" ks_sorting = si.run_sorter(\n",
"INFO:kilosort.io:========================================\n",
"INFO:kilosort.io:Loading recording with SpikeInterface...\n",
"INFO:kilosort.io:number of samples: 18000000\n",
"INFO:kilosort.io:number of channels: 384\n",
"INFO:kilosort.io:numbef of segments: 1\n",
"INFO:kilosort.io:sampling rate: 30000.0\n",
"INFO:kilosort.io:dtype: float32\n",
"INFO:kilosort.io:========================================\n",
"INFO:kilosort.run_kilosort: \n",
"INFO:kilosort.run_kilosort:Computing preprocessing variables.\n",
"INFO:kilosort.run_kilosort:----------------------------------------\n",
"INFO:kilosort.run_kilosort:N samples: 18000000\n",
"INFO:kilosort.run_kilosort:N seconds: 600.0\n",
"INFO:kilosort.run_kilosort:N batches: 300\n",
"INFO:kilosort.run_kilosort:Preprocessing filters computed in 2.11s; total 2.11s\n",
"INFO:kilosort.run_kilosort: \n",
"INFO:kilosort.run_kilosort:Computing drift correction.\n",
"INFO:kilosort.run_kilosort:----------------------------------------\n",
"INFO:kilosort.datashift:nblocks = 0, skipping drift correction\n",
"INFO:kilosort.run_kilosort:drift computed in 0.00s; total 2.17s\n",
"INFO:kilosort.run_kilosort: \n",
"INFO:kilosort.run_kilosort:Extracting spikes using templates\n",
"INFO:kilosort.run_kilosort:----------------------------------------\n",
"INFO:kilosort.spikedetect:Re-computing universal templates from data.\n",
"100%|██████████| 300/300 [05:51<00:00, 1.17s/it]\n",
"INFO:kilosort.run_kilosort:217572 spikes extracted in 354.78s; total 356.95s\n",
"INFO:kilosort.run_kilosort: \n",
"INFO:kilosort.run_kilosort:First clustering\n",
"INFO:kilosort.run_kilosort:----------------------------------------\n",
"100%|██████████| 96/96 [00:32<00:00, 3.00it/s]\n",
"INFO:kilosort.run_kilosort:320 clusters found, in 32.55s; total 389.50s\n",
"INFO:kilosort.run_kilosort: \n",
"INFO:kilosort.run_kilosort:Extracting spikes using cluster waveforms\n",
"INFO:kilosort.run_kilosort:----------------------------------------\n",
"100%|██████████| 300/300 [00:46<00:00, 6.39it/s]\n",
"INFO:kilosort.run_kilosort:235646 spikes extracted in 47.07s; total 436.57s\n",
"INFO:kilosort.run_kilosort: \n",
"INFO:kilosort.run_kilosort:Final clustering\n",
"INFO:kilosort.run_kilosort:----------------------------------------\n",
"100%|██████████| 96/96 [00:26<00:00, 3.66it/s]\n",
"INFO:kilosort.run_kilosort:187 clusters found, in 26.22s; total 462.79s\n",
"INFO:kilosort.run_kilosort: \n",
"INFO:kilosort.run_kilosort:Merging clusters\n",
"INFO:kilosort.run_kilosort:----------------------------------------\n",
"INFO:kilosort.run_kilosort:177 units found, in 0.23s; total 463.03s\n",
"INFO:kilosort.run_kilosort: \n",
"INFO:kilosort.run_kilosort:Saving to phy and computing refractory periods\n",
"INFO:kilosort.run_kilosort:----------------------------------------\n",
"INFO:kilosort.run_kilosort:170 units found with good refractory periods\n",
"INFO:kilosort.run_kilosort:Total runtime: 464.79s = 00:07:45 h:m:s\n",
"INFO:kilosort.run_kilosort:Sorting output saved in: /disk/scratch/mhennig/spikeinterface/HS2/testing/KS4_output/sorter_output.\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"kilosort4 run time 465.66s\n"
]
}
],
"source": [
"if 'rec_in_mem' in globals():\n",
" del(rec_in_mem)\n",
"params = si.Kilosort4Sorter.default_params()\n",
"params.update({'nblocks': 0})\n",
"rec_in_mem = si.load_extractor(recording_name);\n",
"t0 = time.perf_counter()\n",
"ks_sorting = si.run_sorter(\n",
" sorter_name=\"kilosort4\",\n",
" recording=rec_in_mem,\n",
" output_folder=\"KS4_output\",\n",
" remove_existing_folder=True,\n",
" singularity_image=False,\n",
" verbose=True,\n",
" delete_container_files=False,\n",
" delete_output_folder=True,\n",
" **params\n",
")\n",
"t1 = time.perf_counter()\n",
"times['Kilosort4 all'] = t1-t0"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"{'SI detect+COM': 26.24065605085343,\n",
" 'herdingspikes detect': 15.178689972963184,\n",
" 'herdingspikes sort': 5.46234157984145,\n",
" 'herdingspikes all': 20.641031552804634,\n",
" 'Kilosort4 all': 468.0466902530752}"
]
},
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"times"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAjsAAAHkCAYAAADYVu48AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8fJSN1AAAACXBIWXMAAA9hAAAPYQGoP6dpAABg7klEQVR4nO3dd1gUV9sG8HupVlAEQRSxABZAQcSuYMOGxt67JnaDNRpN1Ng1sUSjscaSGLux12iwN+w9KioqiAUpgtTn+4OPeV1Rw8LCwnr/rmsv3TOzy7Nt9t4zZ86oRERAREREpKcMdF0AERERUWZi2CEiIiK9xrBDREREeo1hh4iIiPQaww4RERHpNYYdIiIi0msMO0RERKTXGHaIiIhIrxnpuoDsICkpCU+fPkX+/PmhUql0XQ4RERGlgYggMjIStra2MDD4eP8Nww6Ap0+fws7OTtdlEBERUToEBQWhWLFiH13OsAMgf/78AJKfLDMzMx1XQ0RERGkREREBOzs75Xv8Yxh2AGXXlZmZGcMOERFRDvNfQ1A4QJmIiIj0GsMOERER6TWGHSIiItJrDDtERESk1xh2iIiISK8x7BAREZFeY9ghIiIivcawQ0RERHqNYYeIiIj0GsMOERER6TWGHSIiItJrDDtERESk1xh2iIiISK8x7BAREZFeY9ghIiIivWak6wKIiIj0lceoNbouIccKmN1da/fFnh0iIiLSaww7REREpNcYdoiIiEivMewQERGRXmPYISIiIr3GsENERER6jWGHiIiI9BrDDhEREek1hh0iIiLSaww7REREpNcYdoiIiEivMewQERGRXmPYISIiIr3GsENERER6jWGHiIiI9BrDDhEREek1hh0iIiLSaww7REREpNcYdoiIiEivMewQERGRXmPYISIiIr3GsENERER6jWGHiIiI9BrDDhEREek1hh0iIiLSaww7REREpNcYdoiIiEivMewQERGRXmPYISIiIr3GsENERER6jWGHiIiI9BrDDhEREek1hh0iIiLSaww7REREpNcYdoiIiEivMewQERGRXmPYISIiIr3GsENERER6jWGHiIiI9BrDDhEREek1hh0iIiLSaww7REREpNcYdoiIiEivMewQERGRXmPYISIiIr2WbcLO9OnToVKp4Ofnp7SJCCZOnAhbW1vkzp0b3t7euH79utrtYmNjMWTIEFhaWiJv3rxo0aIFHj9+nMXVExERUXaVLcLOuXPnsHTpUlSoUEGtfdasWZgzZw4WLlyIc+fOwcbGBg0bNkRkZKSyjp+fH7Zt24b169fj+PHjiIqKgq+vLxITE7P6YRAREVE2pPOwExUVhS5dumDZsmUoWLCg0i4imDdvHsaNG4fWrVvDxcUFq1evRnR0NNatWwcACA8Px4oVK/DTTz+hQYMGcHd3x++//46rV6/i0KFDunpIRERElI3oPOwMGjQIzZo1Q4MGDdTaAwMDERISAh8fH6XN1NQUXl5eOHnyJAAgICAA8fHxauvY2trCxcVFWYeIiIg+b0a6/OPr16/HhQsXcO7cuVTLQkJCAADW1tZq7dbW1nj48KGyjomJiVqPUMo6Kbf/kNjYWMTGxirXIyIi0v0YiIiIKHvTWc9OUFAQvv76a/z+++/IlSvXR9dTqVRq10UkVdv7/mud6dOnw9zcXLnY2dlpVjwRERHlGDoLOwEBAQgNDYWHhweMjIxgZGQEf39//PzzzzAyMlJ6dN7voQkNDVWW2djYIC4uDmFhYR9d50PGjh2L8PBw5RIUFKTlR0dERETZhc7CTv369XH16lVcunRJuVSuXBldunTBpUuXUKpUKdjY2ODgwYPKbeLi4uDv748aNWoAADw8PGBsbKy2TnBwMK5du6as8yGmpqYwMzNTuxAREZF+0tmYnfz588PFxUWtLW/evChUqJDS7ufnh2nTpsHR0RGOjo6YNm0a8uTJg86dOwMAzM3N0adPH4wYMQKFChWChYUFRo4cCVdX11QDnomIiOjzpNMByv9l9OjRiImJwcCBAxEWFoaqVaviwIEDyJ8/v7LO3LlzYWRkhPbt2yMmJgb169fHqlWrYGhoqMPKiYiIKLtQiYjoughdi4iIgLm5OcLDw7lLi4iItMZj1Bpdl5BjBczu/p/rpPX7W+fz7BARERFlJoYdIiIi0msMO0RERKTXNB6g/ODBAxw7dgwPHjxAdHQ0rKys4O7ujurVq39yckAiIiIiXUhz2Fm3bh1+/vlnnD17FoULF0bRokWRO3duvHr1Cvfu3UOuXLnQpUsXfPPNN7C3t8/MmomIiIjSLE1hp1KlSjAwMEDPnj2xceNGFC9eXG15bGwsTp06hfXr16Ny5cpYtGgR2rVrlykFExEREWkiTWFn8uTJaNas2UeXm5qawtvbG97e3pgyZQoCAwO1ViARERFRRqQp7Hwq6LzP0tISlpaW6S6IiIiISJsyNINyTEwM4uPj1do4KR8RERFlJxofeh4dHY3BgwejcOHCyJcvHwoWLKh2ISIiIspONA47o0aNwuHDh7Fo0SKYmppi+fLlmDRpEmxtbbFmDafFJiIiouxF491YO3fuxJo1a+Dt7Y3evXujdu3acHBwgL29Pf744w906dIlM+okIiIiSheNe3ZevXqFkiVLAkgen/Pq1SsAQK1atXD06FHtVkdERESUQRqHnVKlSuHBgwcAgPLly2Pjxo0Aknt8ChQooM3aiIiIiDJM47DTq1cvXL58GQAwduxYZezOsGHDMGrUKK0XSERERJQRGo/ZGTZsmPL/unXr4tatWzh//jxKly6NihUrarU4IiIioozSuGdnzZo1iI2NVa4XL14crVu3Rrly5Xg0FhEREWU76dqNFR4enqo9MjISvXr10kpRRERERNqicdgREahUqlTtjx8/hrm5uVaKIiIiItKWNI/ZcXd3h0qlgkqlQv369WFk9L+bJiYmIjAwEI0bN86UIomIiIjSK81hp2XLlgCAS5cuoVGjRsiXL5+yzMTEBCVKlECbNm20XiARERFRRqQ57EyYMAEAUKJECXTo0AG5cuXKtKKIiIiItEXjQ8979OiRGXUQERERZQqNw05iYiLmzp2LjRs34tGjR4iLi1NbnnL6CCIiIqLsQOOjsSZNmoQ5c+agffv2CA8Px/Dhw9G6dWsYGBhg4sSJmVAiERERUfppHHb++OMPLFu2DCNHjoSRkRE6deqE5cuX4/vvv8fp06czo0YiIiKidNM47ISEhMDV1RUAkC9fPmWCQV9fX+zevVu71RERERFlkMZhp1ixYggODgYAODg44MCBAwCAc+fOwdTUVLvVEREREWWQxmGnVatW+PvvvwEAX3/9Nb777js4Ojqie/fu6N27t9YLJCIiIsoIjY/GmjFjhvL/tm3bolixYjh58iQcHBzQokULrRZHRERElFEah533VatWDdWqVdNGLURERERal6aws2PHjjTfIXt3iIiIKDtJU9hJOS9WCpVKBRFJ1QYkTzpIRERElF2kaYByUlKScjlw4ADc3Nywd+9evH79GuHh4di7dy8qVaqEffv2ZXa9RERERBrReMyOn58ffv31V9SqVUtpa9SoEfLkyYOvvvoK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p06d0mpxRERERBmlcdi5evUqWrVqlardysoKL1++1EpRRERERNqicdgpUKAAgoODU7VfvHgRRYsW1UpRRERERNqicdjp3LkzvvnmG4SEhEClUiEpKQknTpzAyJEj0b1798yokYiIiCjdNA47U6dORfHixVG0aFFERUWhfPnyqFOnDmrUqIHx48dnRo1ERERE6abxPDvGxsb4448/MHnyZFy4cAFJSUlwd3eHo6NjZtRHRERElCHpmlQQAEqVKoVSpUohMTERV69eRVhYGAoWLKjN2oiIiIgyTOPdWH5+flixYgUAIDExEV5eXqhUqRLs7Ozwzz//aLs+IiIiogzROOxs3rwZFStWBADs3LkT9+/fx61bt+Dn54dx48ZpvUAiIiKijNA47Lx48QI2NjYAgD179qB9+/ZwcnJCnz59cPXqVa0XSERERJQRGocda2tr3LhxA4mJidi3bx8aNGgAAIiOjoahoaHWCyQiIiLKCI0HKPfq1Qvt27dHkSJFoFKp0LBhQwDAmTNnULZsWa0XSERERJQRGoediRMnwsXFBUFBQWjXrh1MTU0BAIaGhhgzZozWCyQiIiLKiHQdet62bdtUbT169MhwMURERETalqYxO+vXr0/zHQYFBeHEiRPpLoiIiIhIm9IUdhYvXoyyZcti5syZuHnzZqrl4eHh2LNnDzp37gwPDw+8evVK64USERERpUeadmP5+/tj165dWLBgAb799lvkzZsX1tbWyJUrF8LCwhASEgIrKyv06tUL165dQ+HChTO7biIiIqI0SfOYHV9fX/j6+uLly5c4fvw4Hjx4gJiYGFhaWsLd3R3u7u4wMND4SHYiIiKiTKXxAOVChQrhiy++yIxaiIiIiLSOXTFERESk1xh2iIiISK8x7BAREZFeY9ghIiIivZbusBMXF4fbt28jISFBm/UQERERaZXGYSc6Ohp9+vRBnjx54OzsjEePHgEAhg4dihkzZmi9QCIiIqKM0DjsjB07FpcvX8Y///yDXLlyKe0NGjTAhg0btFocERERUUZpPM/OX3/9hQ0bNqBatWpQqVRKe/ny5XHv3j2tFkdERESUURr37Dx//vyDp4N48+aNWvghIiIiyg40Djuenp7YvXu3cj0l4CxbtgzVq1fXXmVEREREWqDxbqzp06ejcePGuHHjBhISEjB//nxcv34dp06dgr+/f2bU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",
"text/plain": [
"<Figure size 640x480 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"sns.barplot(data=times);\n",
"plt.ylabel(\"Execution time (sec/600s data)\");\n",
"plt.xticks(rotation=30);"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python [conda env:si]",
"language": "python",
"name": "conda-env-si-py"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.12.3"
}
},
"nbformat": 4,
"nbformat_minor": 4
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment