
.. DO NOT EDIT.
.. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY.
.. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE:
.. "examples\datasets\plot_data_horsager2009.py"
.. LINE NUMBERS ARE GIVEN BELOW.

.. only:: html

    .. note::
        :class: sphx-glr-download-link-note

        :ref:`Go to the end <sphx_glr_download_examples_datasets_plot_data_horsager2009.py>`
        to download the full example code.

.. rst-class:: sphx-glr-example-title

.. _sphx_glr_examples_datasets_plot_data_horsager2009.py:


===============================================================================
Threshold data from Horsager et al. (2009)
===============================================================================

This example shows how to use the Horsager et al. (2009) dataset.

[Horsager2009]_ used a set of psychophysical detection tasks to determine
perceptual thresholds in two Argus I users.

.. important ::

        You will need to install `Pandas <https://pandas.pydata.org>`_
        (``pip install pandas``) for this dataset.

A typical task involved turning on a single electrode in the array and asking
the subject if they saw something. If the subject did not detect a visual
percept (i.e., a phosphene), the stimulus amplitude was increased.
Using a staircase procedure, the researchers were able to determine the current
amplitude at which subjects were able to detect a phosphene 50% of the time.
This amplitude is called the threshold current, and it is stored in the
"stim_amp" column of the dataset.

.. note ::

    Mean threshold currents were extracted from the main publication and its
    supplementary materials using Webplot Digitizer.
    Therefore, these data are provided without any guarantee of correctness or
    completeness.

Loading the dataset
-------------------

The dataset can be loaded as a Pandas ``DataFrame``:

.. GENERATED FROM PYTHON SOURCE LINES 36-41

.. code-block:: Python


    from pulse2percept.datasets import load_horsager2009
    data = load_horsager2009()
    print(data)





.. rst-class:: sphx-glr-script-out

 .. code-block:: none

        subject implant electrode       task        stim_type  stim_dur  stim_freq  ...  ref_freq     ref_amp  ref_amp_factor  ref_pulse_dur  ref_interphase_dur  theta    source
    0       S05  ArgusI        C3  threshold     single_pulse     200.0        NaN  ...       NaN         NaN             NaN            NaN                 NaN  110.3     fig_3
    1       S05  ArgusI        C3  threshold     single_pulse     200.0        NaN  ...       NaN         NaN             NaN            NaN                 NaN  110.3     fig_3
    2       S05  ArgusI        C3  threshold     single_pulse     200.0        NaN  ...       NaN         NaN             NaN            NaN                 NaN  110.3     fig_3
    3       S05  ArgusI        C3  threshold     single_pulse     200.0        NaN  ...       NaN         NaN             NaN            NaN                 NaN  110.3     fig_3
    4       S05  ArgusI        C3  threshold     single_pulse     200.0        NaN  ...       NaN         NaN             NaN            NaN                 NaN  110.3     fig_3
    ..      ...     ...       ...        ...              ...       ...        ...  ...       ...         ...             ...            ...                 ...    ...       ...
    603     S06  ArgusI        D1  threshold  latent_addition     500.0        NaN  ...       NaN  222.940156             NaN          0.075               0.075  147.0  fig_s3.2
    604     S06  ArgusI        D1  threshold  latent_addition     500.0        NaN  ...       NaN  222.940156             NaN          0.075               0.075  147.0  fig_s3.2
    605     S06  ArgusI        D1  threshold  latent_addition     500.0        NaN  ...       NaN  222.940156             NaN          0.075               0.075  147.0  fig_s3.2
    606     S06  ArgusI        D1  threshold  latent_addition     500.0        NaN  ...       NaN  222.940156             NaN          0.075               0.075  147.0  fig_s3.2
    607     S06  ArgusI        D1  threshold  latent_addition     500.0        NaN  ...       NaN  222.940156             NaN          0.075               0.075  147.0  fig_s3.2

    [608 rows x 21 columns]




.. GENERATED FROM PYTHON SOURCE LINES 43-48

Inspecting the DataFrame tells us that there are 552 threshold measurements
(the rows) each with 21 different attributes (the columns).

These attributes include specifiers such as "subject", "electrode", and
"stim_type". We can print all column names using:

.. GENERATED FROM PYTHON SOURCE LINES 48-51

.. code-block:: Python


    data.columns





.. rst-class:: sphx-glr-script-out

 .. code-block:: none


    Index(['subject', 'implant', 'electrode', 'task', 'stim_type', 'stim_dur',
           'stim_freq', 'stim_amp', 'pulse_type', 'pulse_dur', 'pulse_num',
           'interphase_dur', 'delay_dur', 'ref_stim_type', 'ref_freq', 'ref_amp',
           'ref_amp_factor', 'ref_pulse_dur', 'ref_interphase_dur', 'theta',
           'source'],
          dtype='object')



.. GENERATED FROM PYTHON SOURCE LINES 52-59

.. note ::

    The meaning of all column names is explained in the docstring of
    the :py:func:`~pulse2percept.datasets.load_horsager2009` function.

For example, "stim_type" corresponds to the different stimulus types that
were used in the paper:

.. GENERATED FROM PYTHON SOURCE LINES 59-62

.. code-block:: Python


    data.stim_type.unique()





.. rst-class:: sphx-glr-script-out

 .. code-block:: none


    array(['single_pulse', 'fixed_duration', 'variable_duration',
           'fixed_duration_supra', 'bursting_triplets',
           'bursting_triplets_supra', 'latent_addition'], dtype=object)



.. GENERATED FROM PYTHON SOURCE LINES 63-69

The first entry, "single_pulse", corresponds to the single biphasic pulse
used to produce Figure 3. We can verify which figure a data point came from
by inspecting the "source" column.

To select all the "single_pulse" rows, we can index into the DataFrame as
follows:

.. GENERATED FROM PYTHON SOURCE LINES 69-72

.. code-block:: Python


    print(data[data.stim_type == 'single_pulse'])





.. rst-class:: sphx-glr-script-out

 .. code-block:: none

       subject implant electrode       task     stim_type  stim_dur  stim_freq    stim_amp  ... ref_stim_type  ref_freq  ref_amp  ref_amp_factor  ref_pulse_dur ref_interphase_dur  theta    source
    0      S05  ArgusI        C3  threshold  single_pulse     200.0        NaN  179.792755  ...           NaN       NaN      NaN             NaN            NaN                NaN  110.3     fig_3
    1      S05  ArgusI        C3  threshold  single_pulse     200.0        NaN   97.391689  ...           NaN       NaN      NaN             NaN            NaN                NaN  110.3     fig_3
    2      S05  ArgusI        C3  threshold  single_pulse     200.0        NaN   64.690443  ...           NaN       NaN      NaN             NaN            NaN                NaN  110.3     fig_3
    3      S05  ArgusI        C3  threshold  single_pulse     200.0        NaN   33.039171  ...           NaN       NaN      NaN             NaN            NaN                NaN  110.3     fig_3
    4      S05  ArgusI        C3  threshold  single_pulse     200.0        NaN   29.333355  ...           NaN       NaN      NaN             NaN            NaN                NaN  110.3     fig_3
    ..     ...     ...       ...        ...           ...       ...        ...         ...  ...           ...       ...      ...             ...            ...                ...    ...       ...
    75     S06  ArgusI        D1  threshold  single_pulse     200.0        NaN   66.036679  ...           NaN       NaN      NaN             NaN            NaN                NaN  132.0  fig_s3.1
    76     S06  ArgusI        D1  threshold  single_pulse     200.0        NaN   51.343932  ...           NaN       NaN      NaN             NaN            NaN                NaN  132.0  fig_s3.1
    77     S06  ArgusI        D1  threshold  single_pulse     200.0        NaN   43.346530  ...           NaN       NaN      NaN             NaN            NaN                NaN  132.0  fig_s3.1
    78     S06  ArgusI        D1  threshold  single_pulse     200.0        NaN   35.268438  ...           NaN       NaN      NaN             NaN            NaN                NaN  132.0  fig_s3.1
    79     S06  ArgusI        D1  threshold  single_pulse     200.0        NaN   27.638849  ...           NaN       NaN      NaN             NaN            NaN                NaN  132.0  fig_s3.1

    [80 rows x 21 columns]




.. GENERATED FROM PYTHON SOURCE LINES 73-78

This leaves us with 80 rows, some of which come from Figure 3, others from
Figure S3.1 in the supplementary material.

An alternative to indexing into the DataFrame is to load only a subset of
the data:

.. GENERATED FROM PYTHON SOURCE LINES 78-81

.. code-block:: Python


    print(load_horsager2009(stim_types='single_pulse'))





.. rst-class:: sphx-glr-script-out

 .. code-block:: none

       subject implant electrode       task     stim_type  stim_dur  stim_freq    stim_amp  ... ref_stim_type  ref_freq  ref_amp  ref_amp_factor  ref_pulse_dur ref_interphase_dur  theta    source
    0      S05  ArgusI        C3  threshold  single_pulse     200.0        NaN  179.792755  ...           NaN       NaN      NaN             NaN            NaN                NaN  110.3     fig_3
    1      S05  ArgusI        C3  threshold  single_pulse     200.0        NaN   97.391689  ...           NaN       NaN      NaN             NaN            NaN                NaN  110.3     fig_3
    2      S05  ArgusI        C3  threshold  single_pulse     200.0        NaN   64.690443  ...           NaN       NaN      NaN             NaN            NaN                NaN  110.3     fig_3
    3      S05  ArgusI        C3  threshold  single_pulse     200.0        NaN   33.039171  ...           NaN       NaN      NaN             NaN            NaN                NaN  110.3     fig_3
    4      S05  ArgusI        C3  threshold  single_pulse     200.0        NaN   29.333355  ...           NaN       NaN      NaN             NaN            NaN                NaN  110.3     fig_3
    ..     ...     ...       ...        ...           ...       ...        ...         ...  ...           ...       ...      ...             ...            ...                ...    ...       ...
    75     S06  ArgusI        D1  threshold  single_pulse     200.0        NaN   66.036679  ...           NaN       NaN      NaN             NaN            NaN                NaN  132.0  fig_s3.1
    76     S06  ArgusI        D1  threshold  single_pulse     200.0        NaN   51.343932  ...           NaN       NaN      NaN             NaN            NaN                NaN  132.0  fig_s3.1
    77     S06  ArgusI        D1  threshold  single_pulse     200.0        NaN   43.346530  ...           NaN       NaN      NaN             NaN            NaN                NaN  132.0  fig_s3.1
    78     S06  ArgusI        D1  threshold  single_pulse     200.0        NaN   35.268438  ...           NaN       NaN      NaN             NaN            NaN                NaN  132.0  fig_s3.1
    79     S06  ArgusI        D1  threshold  single_pulse     200.0        NaN   27.638849  ...           NaN       NaN      NaN             NaN            NaN                NaN  132.0  fig_s3.1

    [80 rows x 21 columns]




.. GENERATED FROM PYTHON SOURCE LINES 82-92

Plotting the data
-----------------

Arguably the most important column is "stim_amp". This is the current
amplitude of the different stimuli (single pulse, pulse trains, etc.) used
at threshold.

We might be interested in seeing how threshold amplitude varies as a function
of pulse duration. We could either use Matplotlib to generate a scatter plot
or use pulse2percept's own visualization function:

.. GENERATED FROM PYTHON SOURCE LINES 92-96

.. code-block:: Python


    from pulse2percept.viz import scatter_correlation
    scatter_correlation(data.pulse_dur, data.stim_amp)




.. image-sg:: /examples/datasets/images/sphx_glr_plot_data_horsager2009_001.png
   :alt: plot data horsager2009
   :srcset: /examples/datasets/images/sphx_glr_plot_data_horsager2009_001.png
   :class: sphx-glr-single-img


.. rst-class:: sphx-glr-script-out

 .. code-block:: none


    <Axes: xlabel='pulse_dur', ylabel='stim_amp'>



.. GENERATED FROM PYTHON SOURCE LINES 97-113

:py:func:`~pulse2percept.viz.scatter_correlation` above generates a scatter
plot of the stimulus amplitude as a function of pulse duration, and performs
linear regression to calculate a correlation $r$ and a $p$ value.
As expected from the literature, now it becomes evident that stimulus
amplitude is negatively correlated with pulse duration (no matter the exact
stimulus used).

Recreating the stimuli
----------------------

To recreate the stimulus used to obtain a specific data point, we need to use
the values specified in the different columns of a particular row.

For example, the first row of the dataset specifies the stimulus used to
obtain the threshold current for subject S05 on Electrode C3 using a single
biphasic pulse:

.. GENERATED FROM PYTHON SOURCE LINES 113-117

.. code-block:: Python


    row = data.loc[0, :]
    print(row)





.. rst-class:: sphx-glr-script-out

 .. code-block:: none

    subject                          S05
    implant                       ArgusI
    electrode                         C3
    task                       threshold
    stim_type               single_pulse
    stim_dur                       200.0
    stim_freq                        NaN
    stim_amp                  179.792755
    pulse_type            cathodic_first
    pulse_dur                      0.075
    pulse_num                        1.0
    interphase_dur                 0.075
    delay_dur                        NaN
    ref_stim_type                    NaN
    ref_freq                         NaN
    ref_amp                          NaN
    ref_amp_factor                   NaN
    ref_pulse_dur                    NaN
    ref_interphase_dur               NaN
    theta                          110.3
    source                         fig_3
    Name: 0, dtype: object




.. GENERATED FROM PYTHON SOURCE LINES 118-120

Using :py:class:`~pulse2percept.stimuli.BiphasicPulse`, we can create the
pulse to specifications:

.. GENERATED FROM PYTHON SOURCE LINES 120-127

.. code-block:: Python


    from pulse2percept.stimuli import BiphasicPulse
    stim = BiphasicPulse(row['stim_amp'], row['pulse_dur'],
                         interphase_dur=row['interphase_dur'],
                         stim_dur=row['stim_dur'], electrode=row['electrode'])









.. GENERATED FROM PYTHON SOURCE LINES 128-129

We can zoom in on the first 10 ms to see the stimulus waveform:

.. GENERATED FROM PYTHON SOURCE LINES 129-132

.. code-block:: Python


    import numpy as np
    stim.plot(time=np.arange(0, 10, 0.01))



.. image-sg:: /examples/datasets/images/sphx_glr_plot_data_horsager2009_002.png
   :alt: plot data horsager2009
   :srcset: /examples/datasets/images/sphx_glr_plot_data_horsager2009_002.png
   :class: sphx-glr-single-img


.. rst-class:: sphx-glr-script-out

 .. code-block:: none


    <Axes: ylabel='C3'>




.. rst-class:: sphx-glr-timing

   **Total running time of the script:** (0 minutes 0.279 seconds)


.. _sphx_glr_download_examples_datasets_plot_data_horsager2009.py:

.. only:: html

  .. container:: sphx-glr-footer sphx-glr-footer-example

    .. container:: sphx-glr-download sphx-glr-download-jupyter

      :download:`Download Jupyter notebook: plot_data_horsager2009.ipynb <plot_data_horsager2009.ipynb>`

    .. container:: sphx-glr-download sphx-glr-download-python

      :download:`Download Python source code: plot_data_horsager2009.py <plot_data_horsager2009.py>`

    .. container:: sphx-glr-download sphx-glr-download-zip

      :download:`Download zipped: plot_data_horsager2009.zip <plot_data_horsager2009.zip>`


.. only:: html

 .. rst-class:: sphx-glr-signature

    `Gallery generated by Sphinx-Gallery <https://sphinx-gallery.github.io>`_
