matplotlib-dark 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,19 @@
1
+ """
2
+ matplotlib-dark: matplotlib, but in dark mode
3
+ A lightweight package to apply dark themes to matplotlib plots.
4
+ """
5
+
6
+ __version__ = "0.1.0"
7
+ __author__ = "Eduardo J. Barrios"
8
+
9
+ from .core import dark_mode, dark_theme, get_available_themes, light_mode, set_theme
10
+ from .themes import THEMES
11
+
12
+ __all__ = [
13
+ "dark_mode",
14
+ "dark_theme",
15
+ "light_mode",
16
+ "set_theme",
17
+ "get_available_themes",
18
+ "THEMES",
19
+ ]
@@ -0,0 +1,148 @@
1
+ """Core functionality for matplotlib-dark."""
2
+
3
+ from contextlib import contextmanager
4
+ from typing import Iterator, List, Optional
5
+
6
+ import matplotlib as mpl
7
+ from matplotlib import cycler
8
+
9
+ from .themes import THEMES
10
+
11
+ # Store original rcParams
12
+ _original_params: Optional[dict] = None
13
+
14
+
15
+ def dark_mode(theme: str = "default") -> None:
16
+ """
17
+ Apply a dark theme to matplotlib plots.
18
+
19
+ Parameters
20
+ ----------
21
+ theme : str, optional
22
+ The name of the theme to apply. Available themes:
23
+ 'default', 'nord', 'monokai', 'dracula'
24
+ Default is 'default'.
25
+
26
+ Examples
27
+ --------
28
+ >>> import matplotlib_dark as mdk
29
+ >>> mdk.dark_mode()
30
+ >>> mdk.dark_mode(theme='nord')
31
+ """
32
+ set_theme(theme)
33
+
34
+
35
+ def light_mode() -> None:
36
+ """
37
+ Restore matplotlib to its default light theme.
38
+
39
+ Examples
40
+ --------
41
+ >>> import matplotlib_dark as mdk
42
+ >>> mdk.dark_mode()
43
+ >>> # ... create plots ...
44
+ >>> mdk.light_mode() # Restore defaults
45
+ """
46
+ global _original_params
47
+
48
+ if _original_params is None:
49
+ mpl.rcdefaults()
50
+ else:
51
+ mpl.rcParams.update(_original_params)
52
+ _original_params = None
53
+
54
+
55
+ def set_theme(theme_name: str) -> None:
56
+ """
57
+ Set a specific dark theme.
58
+
59
+ Parameters
60
+ ----------
61
+ theme_name : str
62
+ The name of the theme to apply.
63
+
64
+ Raises
65
+ ------
66
+ ValueError
67
+ If the theme name is not recognized.
68
+ """
69
+ global _original_params
70
+
71
+ if theme_name not in THEMES:
72
+ available = ', '.join(THEMES.keys())
73
+ raise ValueError(
74
+ f"Unknown theme '{theme_name}'. "
75
+ f"Available themes: {available}"
76
+ )
77
+
78
+ # Save original params on first call
79
+ if _original_params is None:
80
+ _original_params = dict(mpl.rcParams)
81
+
82
+ theme = THEMES[theme_name]
83
+
84
+ # Apply theme colors
85
+ mpl.rcParams.update({
86
+ 'figure.facecolor': theme['bg_color'],
87
+ 'axes.facecolor': theme['axes_bg'],
88
+ 'axes.edgecolor': theme['text_color'],
89
+ 'axes.labelcolor': theme['text_color'],
90
+ 'axes.grid': True,
91
+ 'grid.color': theme['grid_color'],
92
+ 'grid.alpha': 0.3,
93
+ 'text.color': theme['text_color'],
94
+ 'xtick.color': theme['text_color'],
95
+ 'ytick.color': theme['text_color'],
96
+ 'legend.facecolor': theme['axes_bg'],
97
+ 'legend.edgecolor': theme['grid_color'],
98
+ 'savefig.facecolor': theme['bg_color'],
99
+ 'savefig.edgecolor': theme['bg_color'],
100
+ })
101
+
102
+ # Set color cycle
103
+ colors = theme.get('colors', [
104
+ '#8FBCBB', '#88C0D0', '#81A1C1', '#5E81AC',
105
+ '#BF616A', '#D08770', '#EBCB8B', '#A3BE8C', '#B48EAD'
106
+ ])
107
+ mpl.rcParams['axes.prop_cycle'] = cycler(color=colors)
108
+
109
+
110
+ def get_available_themes() -> List[str]:
111
+ """
112
+ Get a list of available theme names.
113
+
114
+ Returns
115
+ -------
116
+ list
117
+ List of available theme names.
118
+
119
+ Examples
120
+ --------
121
+ >>> import matplotlib_dark as mdk
122
+ >>> themes = mdk.get_available_themes()
123
+ >>> print(themes)
124
+ ['default', 'nord', 'monokai', 'dracula']
125
+ """
126
+ return list(THEMES.keys())
127
+
128
+
129
+ @contextmanager
130
+ def dark_theme(theme: str = "default") -> Iterator[None]:
131
+ """Temporarily apply a dark theme and restore the current style afterwards.
132
+
133
+ This is safe to nest and is useful when only one plot should use the theme.
134
+
135
+ Examples
136
+ --------
137
+ >>> import matplotlib_dark as mdk
138
+ >>> with mdk.dark_theme("nord"):
139
+ ... pass # Create and save a plot here.
140
+ """
141
+ global _original_params
142
+ previous_original = _original_params
143
+ with mpl.rc_context():
144
+ set_theme(theme)
145
+ try:
146
+ yield
147
+ finally:
148
+ _original_params = previous_original
@@ -0,0 +1 @@
1
+
@@ -0,0 +1,104 @@
1
+ """Dark theme definitions for matplotlib-dark"""
2
+
3
+ THEMES = {
4
+ 'default': {
5
+ 'bg_color': '#1e1e1e',
6
+ 'axes_bg': '#2d2d2d',
7
+ 'text_color': '#e4e4e4',
8
+ 'grid_color': '#505050',
9
+ 'colors': [
10
+ '#61AFEF', # Blue
11
+ '#98C379', # Green
12
+ '#E06C75', # Red
13
+ '#C678DD', # Purple
14
+ '#56B6C2', # Cyan
15
+ '#E5C07B', # Yellow
16
+ '#D19A66', # Orange
17
+ ]
18
+ },
19
+
20
+ 'nord': {
21
+ 'bg_color': '#2E3440',
22
+ 'axes_bg': '#3B4252',
23
+ 'text_color': '#ECEFF4',
24
+ 'grid_color': '#4C566A',
25
+ 'colors': [
26
+ '#88C0D0', # Frost Blue
27
+ '#A3BE8C', # Aurora Green
28
+ '#EBCB8B', # Aurora Yellow
29
+ '#D08770', # Aurora Orange
30
+ '#BF616A', # Aurora Red
31
+ '#B48EAD', # Aurora Purple
32
+ '#5E81AC', # Frost Dark Blue
33
+ '#8FBCBB', # Frost Teal
34
+ '#81A1C1', # Frost Light Blue
35
+ ]
36
+ },
37
+
38
+ 'monokai': {
39
+ 'bg_color': '#272822',
40
+ 'axes_bg': '#3E3D32',
41
+ 'text_color': '#F8F8F2',
42
+ 'grid_color': '#75715E',
43
+ 'colors': [
44
+ '#66D9EF', # Cyan
45
+ '#A6E22E', # Green
46
+ '#F92672', # Pink
47
+ '#FD971F', # Orange
48
+ '#AE81FF', # Purple
49
+ '#E6DB74', # Yellow
50
+ ]
51
+ },
52
+
53
+ 'dracula': {
54
+ 'bg_color': '#282A36',
55
+ 'axes_bg': '#44475A',
56
+ 'text_color': '#F8F8F2',
57
+ 'grid_color': '#6272A4',
58
+ 'colors': [
59
+ '#8BE9FD', # Cyan
60
+ '#50FA7B', # Green
61
+ '#FFB86C', # Orange
62
+ '#FF79C6', # Pink
63
+ '#BD93F9', # Purple
64
+ '#FF5555', # Red
65
+ '#F1FA8C', # Yellow
66
+ ]
67
+ },
68
+
69
+ 'neon': {
70
+ 'bg_color': '#0a0a0a',
71
+ 'axes_bg': '#1a1a1a',
72
+ 'text_color': '#ffffff',
73
+ 'grid_color': '#ffffff40',
74
+ 'colors': [
75
+ '#00ffff', # Cyan neón
76
+ '#00ff00', # Verde neón
77
+ '#ff00ff', # Magenta neón
78
+ '#ffff00', # Amarillo neón
79
+ '#ff0080', # Rosa neón
80
+ '#00ff80', # Verde-cyan neón
81
+ '#ff00ff', # Púrpura neón
82
+ '#ff8000', # Naranja neón
83
+ '#0080ff', # Azul neón
84
+ ]
85
+ },
86
+
87
+ 'material': {
88
+ 'bg_color': '#212121',
89
+ 'axes_bg': '#303030',
90
+ 'text_color': '#FFFFFF',
91
+ 'grid_color': '#424242',
92
+ 'colors': [
93
+ '#2196F3', # Material Blue
94
+ '#4CAF50', # Material Green
95
+ '#FF5722', # Material Deep Orange
96
+ '#9C27B0', # Material Purple
97
+ '#00BCD4', # Material Cyan
98
+ '#FFEB3B', # Material Yellow
99
+ '#E91E63', # Material Pink
100
+ '#FF9800', # Material Orange
101
+ '#009688', # Material Teal
102
+ ]
103
+ },
104
+ }
@@ -0,0 +1,130 @@
1
+ Metadata-Version: 2.4
2
+ Name: matplotlib-dark
3
+ Version: 0.1.0
4
+ Summary: Automatic dark themes for Matplotlib, with one-line activation
5
+ Author-email: "Eduardo J. Barrios" <edujbarrios@outlook.com>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/edujbarrios/matplotlib-dark
8
+ Project-URL: Documentation, https://github.com/edujbarrios/matplotlib-dark#readme
9
+ Project-URL: Repository, https://github.com/edujbarrios/matplotlib-dark
10
+ Project-URL: Issues, https://github.com/edujbarrios/matplotlib-dark/issues
11
+ Project-URL: Changelog, https://github.com/edujbarrios/matplotlib-dark/blob/main/CHANGELOG.md
12
+ Keywords: matplotlib,dark-mode,visualization,plotting,theme
13
+ Classifier: Development Status :: 4 - Beta
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: Intended Audience :: Science/Research
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.9
18
+ Classifier: Programming Language :: Python :: 3.10
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Topic :: Scientific/Engineering :: Visualization
22
+ Requires-Python: >=3.9
23
+ Description-Content-Type: text/markdown
24
+ License-File: LICENSE
25
+ Requires-Dist: matplotlib>=3.5.0
26
+ Provides-Extra: test
27
+ Requires-Dist: pytest>=7; extra == "test"
28
+ Provides-Extra: dev
29
+ Requires-Dist: build>=1; extra == "dev"
30
+ Requires-Dist: pytest>=7; extra == "dev"
31
+ Requires-Dist: twine>=5; extra == "dev"
32
+ Dynamic: license-file
33
+
34
+ <div align="center">
35
+
36
+ # matplotlib-dark
37
+
38
+ **Automatic dark mode for Matplotlib — polished charts without designing a theme.**
39
+
40
+ [![CI](https://github.com/edujbarrios/matplotlib-dark/actions/workflows/ci.yml/badge.svg)](https://github.com/edujbarrios/matplotlib-dark/actions/workflows/ci.yml)
41
+ [![PyPI](https://img.shields.io/pypi/v/matplotlib-dark)](https://pypi.org/project/matplotlib-dark/)
42
+ [![Python](https://img.shields.io/pypi/pyversions/matplotlib-dark)](https://pypi.org/project/matplotlib-dark/)
43
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
44
+
45
+ </div>
46
+
47
+ `matplotlib-dark` is the automatic alternative to hand-picking backgrounds,
48
+ grid colors, text contrast, and line palettes for every chart. Activate it in
49
+ one line, then keep using the Matplotlib API you already know.
50
+
51
+ ![Six matplotlib-dark themes compared](https://raw.githubusercontent.com/edujbarrios/matplotlib-dark/main/images/theme_comparison.png)
52
+
53
+ ## Installation
54
+
55
+ ```bash
56
+ python -m pip install matplotlib-dark
57
+ ```
58
+
59
+ Python 3.9+ and Matplotlib 3.5+ are supported.
60
+
61
+ ## Quick start
62
+
63
+ ```python
64
+ import matplotlib.pyplot as plt
65
+ import matplotlib_dark as mdk
66
+
67
+ mdk.dark_mode() # That's it: every following chart uses dark mode.
68
+
69
+ plt.plot([1, 2, 3, 4], [1, 4, 2, 3])
70
+ plt.title("Ready for the dark")
71
+ plt.show()
72
+ ```
73
+
74
+ No custom CSS, manual color selection, or complex design code is required.
75
+
76
+ ## Choose a theme
77
+
78
+ ```python
79
+ mdk.dark_mode("nord")
80
+ ```
81
+
82
+ Six ready-to-use themes are included: `default`, `nord`, `monokai`,
83
+ `dracula`, `neon`, and `material`.
84
+
85
+ ```python
86
+ print(mdk.get_available_themes())
87
+ ```
88
+
89
+ ## Apply dark mode temporarily
90
+
91
+ Use the context manager when only some charts should be dark. Your previous
92
+ Matplotlib configuration is restored automatically, even if plotting fails.
93
+
94
+ ```python
95
+ with mdk.dark_theme("dracula"):
96
+ plt.plot([1, 2, 3], [3, 1, 4])
97
+ plt.savefig("dark-chart.png")
98
+ ```
99
+
100
+ For global mode, restore your original configuration explicitly:
101
+
102
+ ```python
103
+ mdk.dark_mode("material")
104
+ # Create charts...
105
+ mdk.light_mode()
106
+ ```
107
+
108
+ ## Why matplotlib-dark?
109
+
110
+ - One-line automatic dark mode
111
+ - Six coordinated color palettes
112
+ - Works with the complete Matplotlib API
113
+ - Global mode or safe, temporary context manager
114
+ - Dark backgrounds are preserved when saving figures
115
+ - Zero dependencies beyond Matplotlib
116
+
117
+ ## Development
118
+
119
+ ```bash
120
+ git clone https://github.com/edujbarrios/matplotlib-dark.git
121
+ cd matplotlib-dark
122
+ python -m pip install -e ".[dev]"
123
+ python -m pytest
124
+ python -m build
125
+ python -m twine check dist/*
126
+ ```
127
+
128
+ ## License
129
+
130
+ MIT © Eduardo J. Barrios
@@ -0,0 +1,9 @@
1
+ matplotlib_dark/__init__.py,sha256=dthpJihzhPnyNsT2hVOKS78FXYiXt4PyCrQM173hxAc,432
2
+ matplotlib_dark/core.py,sha256=teJVi8LWErzL1bAwi7JwoYv-fQ2yWbg2h1YqG807JUE,3872
3
+ matplotlib_dark/py.typed,sha256=frcCV1k9oG9oKj3dpUqdJg1PxRT2RSN_XKdLCPjaYaY,2
4
+ matplotlib_dark/themes.py,sha256=xVhE9ioNZuWWMGceZaUP_wXZts8ZHxVfGGtP64f0HXo,2997
5
+ matplotlib_dark-0.1.0.dist-info/licenses/LICENSE,sha256=qf7ICHSQj1yOZ-yhcQ2UiQzdKXq_dt4GL7H3tB_yjoQ,1096
6
+ matplotlib_dark-0.1.0.dist-info/METADATA,sha256=zgkA7YhDqf_XMjBSrYqAfEjWNgy1saRZSebottuqq1I,4139
7
+ matplotlib_dark-0.1.0.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
8
+ matplotlib_dark-0.1.0.dist-info/top_level.txt,sha256=YrcZD7XFboO54VeV6Z-pfepceJjWCvVaPXK3ZMBICZg,16
9
+ matplotlib_dark-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (84.0.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Eduardo J. Barrios
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1 @@
1
+ matplotlib_dark