Skip to content
Open
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
36 changes: 36 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [1.1.0] - 2025-08-14

### Added
- **Lines function**: New functionality for drawing lines on basketball courts
- Support for basic lines, comet lines (increasing width), and transparent lines (increasing opacity)
- Colormap integration for lines
- Coordinate transformation support for all court orientations
- Basketball-specific applications (pass visualization, player movement tracking)
- Comprehensive error handling and validation
- Performance optimized using matplotlib's LineCollection
- **Documentation**: Complete usage guide and examples in README.md
- **Testing**: 12 comprehensive test cases covering all functionality
- **Examples**: New example scripts demonstrating Lines usage

### Technical Details
- New module: `mplbasketball.lines`
- New function: `Lines()` with extensive parameter support
- Integration with existing coordinate transformation system
- Compatible with all court types (NBA, WNBA, NCAA, FIBA)

## [1.0.0] - Initial Release - 2024-09-07

### Added
- Court class for 2D basketball court visualization
- Court3D class for 3D basketball court visualization
- Support for multiple court types (NBA, WNBA, NCAA, FIBA)
- Coordinate transformation utilities
- Integration with matplotlib functions
- Comprehensive documentation and examples
26 changes: 26 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

**A Python plotting library to visualize basketball data, created by the Sport Performance Lab (SPL) at Maple Leaf Sports & Entertainment (MLSE), Toronto, Canada.**

[![PyPI version](https://badge.fury.io/py/mplbasketball.svg)](https://badge.fury.io/py/mplbasketball)

[Sport Performance Lab (SPL)](https://www.mlsedigital.com/innovation-initiatives/sport-performance-lab) is a Research and Development group that works across all MLSE teams on strategic research initiatives in sports analytics and player performance.

# Quick start
Expand Down Expand Up @@ -54,6 +56,7 @@ Currently, you can use `mplbasketball` to
4. [FIBA](https://nz.basketball/wp-content/uploads/2020/02/FIBA-Basketball-Court-Dimensions.pdf)
2. View data in different orientations orientation (horizontal, vertical, and also normalized to left/right/up/down). The [`utils.transform`](./mplbasketball/utils.py) function makes going between orientations extremely easy and seamless.
3. Easily interface with existing `matplotlib` functions.
4. Draw lines with various effects (comet, transparent, colormap) using the `Lines` function

# Before you begin

Expand Down Expand Up @@ -253,6 +256,29 @@ ax.imshow(heatmap_2.T, extent=extent_2, origin='lower', cmap='cividis', zorder=-
<img src="https://raw.githubusercontent.com/mlsedigital/mplbasketball/main/figs/heatmap.png" width="75%">
</p>

## The Lines function

The `Lines` function provides a way to draw lines on basketball courts with various visual effects. It's particularly useful for visualizing passes, player movements, and other line-based data.

### Basic usage

```python
from mplbasketball import Court, Lines

court = Court(court_type="nba", origin="center")
fig, ax = court.draw(orientation="h")

# Draw a simple line
Lines(0, 0, 20, 20, color="red", linewidth=3, ax=ax)

# Draw multiple lines
Lines([-20, 20], [10, -10], [20, -20], [-10, 10],
color=["red", "blue"], linewidth=3, ax=ax)
```
<p align="center">
<img src="https://raw.githubusercontent.com/mlsedigital/mplbasketball/main/figs/completed_passes.png" width="100%">
</p>

# Documentation

Full documentation coming soon. In the meantime, check out the examples in this README, as well as some of our [examples](https://github.com/mlsedigital/mplbasketball/tree/main/examples)!
Expand Down
93 changes: 93 additions & 0 deletions examples/plot_lines.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
"""
Example demonstrating the lines functionality in mplbasketball.

This example shows how to use the Lines function to draw various types of lines
on basketball courts, including basic lines, comet lines, transparent lines,
and lines with colormaps. This version simulates a high-intensity basketball game
with many passes and movements.
"""

import matplotlib.pyplot as plt
import numpy as np

from mplbasketball import Court, Lines


def generate_pass_data(n_passes=200):
"""Generate realistic basketball pass data."""
passes = []

# Define court boundaries (NBA court in feet)
court_width = 94
court_height = 50

for _ in range(n_passes):
# Only assist passes
# Short to medium passes
x1 = np.random.uniform(-40, 40)
y1 = np.random.uniform(-20, 20)
x2 = x1 + np.random.uniform(-15, 15)
y2 = y1 + np.random.uniform(-15, 15)

# Ensure coordinates are within court bounds
x1 = np.clip(x1, -47, 47)
y1 = np.clip(y1, -25, 25)
x2 = np.clip(x2, -47, 47)
y2 = np.clip(y2, -25, 25)

passes.append((x1, y1, x2, y2, 'completed'))

return passes


def main():
# Create a court
court = Court(court_type="nba", origin="center")
fig, ax = court.draw(orientation="h", showaxis=False)

# Generate pass data
print("Generating pass data...")
passes = generate_pass_data(n_passes=300)

# Define styles for completed passes
completed_style = {
'color': 'gold',
'linewidth': 2,
'comet': True,
'transparent': False
}

# Draw passes
print("Drawing passes...")
for x_start, y_start, x_end, y_end, pass_type in passes:
style = completed_style.copy()

# Add some randomness to make it look more realistic
x_start += np.random.normal(0, 1)
y_start += np.random.normal(0, 1)
x_end += np.random.normal(0, 1)
y_end += np.random.normal(0, 1)

# Draw the pass
Lines(x_start, y_start, x_end, y_end, ax=ax, **style)



# Add title and adjust layout
plt.title("Basketball Game Simulation - Completed Passes\nUsing mplbasketball Lines Function",
fontsize=14, fontweight='bold', color='white')

# Add legend
legend_elements = [
plt.Line2D([0], [0], color='gold', linewidth=3, label='Completed Passes')
]

ax.legend(handles=legend_elements, loc='upper right',
bbox_to_anchor=(1.15, 1), fontsize=10)

plt.tight_layout()
plt.show()


if __name__ == "__main__":
main()
Binary file added figs/completed_passes.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 2 additions & 1 deletion mplbasketball/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from .court import Court
from .court3d import Court3D
from .lines import Lines

__all__ = ["Court", "Court3D"]
__all__ = ["Court", "Court3D", "Lines"]
Loading