Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/workflows/deply_docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ name: Deploy Documentation
on:
push:
branches: [ main ]
paths:
- 'docs/**'
- '.github/workflows/deply_docs.yml'

permissions:
contents: write
Expand Down
35 changes: 35 additions & 0 deletions docs/source/introduction.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,36 @@ This project aims to analyze user interaction with web applications by processin

It provides tools to compute various interaction related metrics (like velocity, acceleration, auc, etc.) and other useful functionalities to facilitate the analysis of user behavior, such as stroke visualization or video generation of user sessions.

Rationale
=============
...

The analyisis of mouse interaction has been widely used in HCI to infer in several aspects of the users interaction with the system.
This mouse dynamics have been proven useful for analysing bheavioral patterns :cite:p:`Katerina2018-ch,Cepeda2018-kn`,
cognitive and physicial conditions affecting the user :cite:p:`Seelye2015-yxm, Khan2008-is, Rhim2023-uz`
or even for user identification :cite:p:`Karim2020-ss` and authentication :cite:p:`Monrose-2000-oc`.

One could enumerate hundreads of research works in this field that have analyzed mouse interaction data to extract meaningful insights about user behavior.
However, there is a lack of dedicated tools and libraries to facilitate this analysis, which is a gap that **pywib** aims to address.

As of 2026, there are no other Python libraries specifically designed for analyzing web interaction behavior in HCI research.
While there are libraries for this same purpose in other programming languages, such as R's `mousemove` :cite:p:`Wulff2025-bt`,
they may not be as accessible to researchers who primarily use Python for data analysis and machine learning tasks, limiting as well
the integration with other Python-based tools and libraries commonly used in HCI research or the automation of analysis pipelines using Python based APIs.

Validity of Metrics
--------------------
One of the main problems when dealing with a library that aims to cover computation of, at most, the most common metrics in HCI research is the validity of such ones.
For this reason, **pywib** has been developed taking into account the most relevant metrics used in research works, that have been proven to be representative of user behavior in different contexts.
This does not mean that the developer team will not expand the library with new metrics in the future, if there is a given need for them, but rather that the initial set of metrics that have been included are those that could be initialy proven to be mathematically and experimentally valid.

Context Specific Metrics
~~~~~~~~~~~~~~~~~~~~~~~~~~~
It is important to note that not all metrics are equally valid in all contexts.
For example, metrics that are valid for analyzing mouse movements in a desktop web application may not be valid for analyzing touch interactions on mobile devices.
Therefore, it is crucial to consider the context in which the metrics will be applied and to validate them accordingly.

Moreover, the setup of an experiment itself can influence the validity of certain metrics :cite:p:`Schoemann2019-vv,Kuric2024-wc`, which is why **pywib** encourages users to validate the metrics they compute in their specific context and experiment setup.

Installation
-------------
Expand All @@ -32,3 +61,9 @@ Small Example

v = velocity(df_all_sessions)
v_metrics = velocity_metrics(None, v)

References
=============

.. bibliography:: references.bib
:style: apa
113 changes: 113 additions & 0 deletions docs/source/references.bib
Original file line number Diff line number Diff line change
Expand Up @@ -391,3 +391,116 @@ @ARTICLE{Vizer2009-sg


@phdthesis{Dijkstra_2013, title={The diagnosis of self-efficacy using mouse and keyboard input}, author={Dijkstra, Maarten}, year={2013}, school={Utrecht University} }

@ARTICLE{Kuric2024-wc,
title = "Is mouse dynamics information credible for user behavior
research? An empirical investigation",
author = "Kuric, Eduard and Demcak, Peter and Krajcovic, Matus and Nemcek,
Peter",
journal = "Comput. Stand. Interfaces",
publisher = "Elsevier BV",
volume = 90,
number = 103849,
pages = "103849",
month = aug,
year = 2024,
copyright = "http://creativecommons.org/licenses/by/4.0/",
language = "en"
}

@ARTICLE{Wulff2025-bt,
title = "Movement tracking of psychological processes: A tutorial using
mousetrap",
author = "Wulff, Dirk U and Kieslich, Pascal J and Henninger, Felix and
Haslbeck, Jonas M B and Schulte-Mecklenbeck, Michael",
abstract = "Movement tracking is a novel process-tracing method that
promises unique access to the temporal dynamics of psychological
processes. The method involves high-resolution tracking of a
hand or handheld device (e.g., a computer mouse) while it is
used to make a choice. In contrast to other process-tracing
methods, which mostly focus on information acquisition, movement
tracking focuses on the processes of information integration and
preference formation. In this article, we present a tutorial on
movement tracking of psychological processes with the mousetrap
R package. We address all steps of the research process, from
design to interpretation, with a particular focus on data
processing and analysis and featuring both established and novel
approaches. Using a representative working example, we
demonstrate how the various steps of movement-tracking analysis
can be implemented with mousetrap and provide thorough
explanations of their theoretical background and interpretation.
Finally, we present a list of recommendations to assist
researchers in addressing their own research questions using
movement tracking of psychological processes.",
journal = "Behav. Res. Methods",
publisher = "Springer Science and Business Media LLC",
volume = 57,
number = 11,
pages = "307",
month = oct,
year = 2025,
keywords = "Cognitive processes; Decision making; Movement tracking; Process
tracing",
copyright = "https://creativecommons.org/licenses/by/4.0",
language = "en"
}

@ARTICLE{Schoemann2019-vv,
title = "Validating mouse-tracking: How design factors influence action
dynamics in intertemporal decision making",
author = "Schoemann, Martin and L{\"u}ken, Malte and Grage, Tobias and
Kieslich, Pascal J and Scherbaum, Stefan",
abstract = "Mouse-tracking is an increasingly popular process-tracing
method. It builds on the assumption that the continuity of
cognitive processing leaks into the continuity of mouse
movements. Because this assumption is the prerequisite for
meaningful reverse inference, it is an important question
whether the assumed interaction between continuous processing
and movement might be influenced by the methodological setup of
the measurement. Here we studied the impacts of three commonly
occurring methodological variations on the quality of
mouse-tracking measures, and hence, on the reported cognitive
effects. We used a mouse-tracking version of a classical
intertemporal choice task that had previously been used to
examine the dynamics of temporal discounting and the date-delay
effect (Dshemuchadse, Scherbaum, \& Goschke, 2013). The data
from this previous study also served as a benchmark condition in
our experimental design. Between studies, we varied the starting
procedure. Within the new study, we varied the response
procedure and the stimulus position. The starting procedure had
the strongest influence on common mouse-tracking measures, and
therefore on the cognitive effects. The effects of the response
procedure and the stimulus position were weaker and less
pronounced. The results suggest that the methodological setup
crucially influences the interaction between continuous
processing and mouse movement. We conclude that the
methodological setup is of high importance for the validity of
mouse-tracking as a process-tracing method. Finally, we discuss
the need for standardized mouse-tracking setups, for which we
provide recommendations, and present two promising lines of
research toward obtaining an evidence-based gold standard of
mouse-tracking.",
journal = "Behav. Res. Methods",
publisher = "Springer Science and Business Media LLC",
volume = 51,
number = 5,
pages = "2356--2377",
month = oct,
year = 2019,
keywords = "Action dynamics; Boundary conditions; Intertemporal choice;
Mouse-tracking; Process-tracing",
language = "en"
}

@ARTICLE{Karim2020-ss,
title = "A study on mouse movement features to identify user",
author = "Karim, Masud and Hasanuzzaman, Md",
journal = "Sci. Res. J.",
publisher = "Scientific Research Journal SCIRJ",
volume = 08,
number = 04,
pages = "77--82",
month = apr,
year = 2020
}

2 changes: 1 addition & 1 deletion src/pywib/core/keyboard.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import numpy as np
from pywib.utils.segmentation import extract_keystroke_traces_by_session
from pywib.utils.validation import validate_dataframe_keyboard
from pywib.constants import EventTypes, ColumnNames, KeyCodeEvents
from pywib.constants import EventTypes, ColumnNames
from pywib.utils.keyboard import (backspace_usage_df, backspace_usage_traces, typing_durations_df, typing_durations_traces, typing_speed_df, typing_speed_traces)

def typing_durations(df: pd.DataFrame = None, traces: dict[str, list[pd.DataFrame]] = None, per_traces: bool = True) -> list:
Expand Down
6 changes: 5 additions & 1 deletion src/pywib/core/movement.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
auc_ratio_traces, auc_ratio_df)
from pywib.constants import ColumnNames

def velocity(df: pd.DataFrame = None, traces: dict[str, list[pd.DataFrame]] = None, per_traces: bool = False) -> dict[str, list[pd.DataFrame]]:
def velocity(df: pd.DataFrame = None, traces: dict[str, list[pd.DataFrame]] = None, per_traces: bool = False, parallel:bool = False, n_jobs: int = 2) -> dict[str, list[pd.DataFrame]]:
"""
Function to calculate velocity for either a single DataFrame or a traces dictionary.

Expand All @@ -34,6 +34,10 @@ def velocity(df: pd.DataFrame = None, traces: dict[str, list[pd.DataFrame]] = No
validate_dataframe(df)
traces = extract_traces_by_session(df)

if parallel:
# Compute velocity for each trace in parallel
return velocity_traces_parallel(traces, n_jobs=n_jobs)

# Compute velocity for each trace
return velocity_traces(traces)

Expand Down
1 change: 0 additions & 1 deletion src/pywib/utils/keyboard.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@

import pandas as pd
import numpy as np
from pywib.constants import ColumnNames, EventTypes, KeyCodeEvents
from pywib.utils.validation import validate_dataframe_keyboard

Expand Down
24 changes: 23 additions & 1 deletion src/pywib/utils/movement.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,29 @@ def velocity_traces(traces: dict[str, list[pd.DataFrame]]) -> dict[str, list[pd.
traces[session_id] = session_traces
return traces

import pandas as pd
def velocity_traces_parallel(traces: dict[str, list[pd.DataFrame]], n_jobs: int = 2) -> dict[str, list[pd.DataFrame]]:
"""
Calculate velocity for a dictionary of traces (each a list of DataFrames) in parallel.

Parameters:
traces (dict[str, list[pd.DataFrame]]): Mapping of sessionId to list of DataFrames.
n_jobs (int): Number of parallel jobs.

Returns:
dict[str, list[pd.DataFrame]]: Same structure, but with velocity computed in each DataFrame.
"""
from joblib import Parallel, delayed

def compute_velocity_for_trace(df):
validate_dataframe(df)
return velocity_df(df)

for session_id, session_traces in traces.items():
session_traces = Parallel(n_jobs=n_jobs)(
delayed(compute_velocity_for_trace)(df) for df in session_traces
)
traces[session_id] = session_traces
return traces

def acceleration_df(df: pd.DataFrame) -> pd.DataFrame:
"""
Expand Down