Skip to content

Commit 06b498e

Browse files
authored
Merge pull request #534 from nschloe/new-mpl
update test mpl version
2 parents fe5dcf5 + c3bb690 commit 06b498e

File tree

83 files changed

+977
-938
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

83 files changed

+977
-938
lines changed

.pre-commit-config.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ repos:
55
- id: isort
66

77
- repo: https://github.com/psf/black
8-
rev: 21.12b0
8+
rev: 22.1.0
99
hooks:
1010
- id: black
1111
language_version: python3

justfile

+4-13
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,12 @@
1-
version := `python3 -c "from configparser import ConfigParser; p = ConfigParser(); p.read('setup.cfg'); print(p['metadata']['version'])"`
2-
name := `python3 -c "from configparser import ConfigParser; p = ConfigParser(); p.read('setup.cfg'); print(p['metadata']['name'])"`
3-
1+
version := `python3 -c "from src.tikzplotlib.__about__ import __version__; print(__version__)"`
42

53
default:
64
@echo "\"just publish\"?"
75

8-
tag:
9-
@if [ "$(git rev-parse --abbrev-ref HEAD)" != "main" ]; then exit 1; fi
10-
curl -H "Authorization: token `cat ~/.github-access-token`" -d '{"tag_name": "v{{version}}"}' https://api.github.com/repos/nschloe/{{name}}/releases
11-
12-
upload: clean
6+
publish:
137
@if [ "$(git rev-parse --abbrev-ref HEAD)" != "main" ]; then exit 1; fi
14-
# https://stackoverflow.com/a/58756491/353337
15-
python3 -m build --sdist --wheel .
16-
twine upload dist/*
17-
18-
publish: tag upload
8+
gh release create "v{{version}}"
9+
flit publish
1910

2011
clean:
2112
@find . | grep -E "(__pycache__|\.pyc|\.pyo$)" | xargs rm -rf

pyproject.toml

+37-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,41 @@
11
[build-system]
2-
requires = ["setuptools>=42", "wheel"]
3-
build-backend = "setuptools.build_meta"
2+
requires = ["flit_core >=3.2,<4"]
3+
build-backend = "flit_core.buildapi"
44

55
[tool.isort]
66
profile = "black"
7+
8+
[project]
9+
name = "tikzplotlib"
10+
authors = [{name = "Nico Schlömer", email = "nico.schloemer@gmail.com"}]
11+
description = "Convert matplotlib figures into TikZ/PGFPlots"
12+
readme = "README.md"
13+
license = {file = "LICENSE"}
14+
classifiers = [
15+
"Development Status :: 5 - Production/Stable",
16+
"Framework :: Matplotlib",
17+
"License :: OSI Approved :: MIT License",
18+
"Operating System :: OS Independent",
19+
"Programming Language :: Python",
20+
"Programming Language :: Python :: 3",
21+
"Programming Language :: Python :: 3.7",
22+
"Programming Language :: Python :: 3.8",
23+
"Programming Language :: Python :: 3.9",
24+
"Programming Language :: Python :: 3.10",
25+
"Topic :: Multimedia :: Graphics :: Graphics Conversion",
26+
"Topic :: Scientific/Engineering :: Visualization",
27+
]
28+
keywords = ["latex", "tikz", "matplotlib", "graphics"]
29+
dynamic = ["version"]
30+
requires-python = ">=3.7"
31+
dependencies = [
32+
"matplotlib >= 1.4.0",
33+
"numpy",
34+
"Pillow",
35+
"webcolors",
36+
]
37+
38+
[project.urls]
39+
Code = "https://github.com/nschloe/tikzplotlib"
40+
Issues = "https://github.com/nschloe/tikzplotlib/issues"
41+
Funding = "https://github.com/sponsors/nschloe"

setup.cfg

-47
This file was deleted.

src/tikzplotlib/__about__.py

+1-10
Original file line numberDiff line numberDiff line change
@@ -1,10 +1 @@
1-
try:
2-
# Python 3.8
3-
from importlib import metadata
4-
except ImportError:
5-
import importlib_metadata as metadata
6-
7-
try:
8-
__version__ = metadata.version("tikzplotlib")
9-
except Exception:
10-
__version__ = "unknown"
1+
__version__ = "0.10.0"

src/tikzplotlib/_axes.py

+11-5
Original file line numberDiff line numberDiff line change
@@ -630,13 +630,19 @@ def _get_ticks(data, xy, ticks, ticklabels):
630630

631631
def _is_colorbar_heuristic(obj):
632632
"""Find out if the object is in fact a color bar."""
633-
# TODO come up with something more accurate here
633+
# Not sure if these properties are always present
634+
if hasattr(obj, "_colorbar") or hasattr(obj, "_colorbar_info"):
635+
return True
636+
637+
# TODO come up with something more accurate here. See
638+
# <https://discourse.matplotlib.org/t/find-out-if-an-axes-object-is-a-colorbar/22563>
634639
# Might help:
635640
# TODO Are the colorbars exactly the l.collections.PolyCollection's?
641+
636642
try:
637643
aspect = float(obj.get_aspect())
638644
except ValueError:
639-
# e.g., aspect == 'equal'
645+
# e.g., aspect in ['equal', 'auto']
640646
return False
641647

642648
# Assume that something is a colorbar if and only if the ratio is above 5.0
@@ -646,10 +652,10 @@ def _is_colorbar_heuristic(obj):
646652
#
647653
# plt.colorbar(im, aspect=5)
648654
#
649-
limit_ratio = 5.0
655+
threshold_ratio = 5.0
650656

651-
return (aspect >= limit_ratio and len(obj.get_xticks()) == 0) or (
652-
aspect <= 1.0 / limit_ratio and len(obj.get_yticks()) == 0
657+
return (aspect >= threshold_ratio and len(obj.get_xticks()) == 0) or (
658+
aspect <= 1.0 / threshold_ratio and len(obj.get_yticks()) == 0
653659
)
654660

655661

src/tikzplotlib/_color.py

+61-54
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,48 @@
11
import matplotlib as mpl
22
import numpy as np
3+
import webcolors
4+
5+
# RGB values (as taken from xcolor.dtx):
6+
builtin_colors = {
7+
"white": [1, 1, 1],
8+
"lightgray": [0.75, 0.75, 0.75],
9+
"gray": [0.5, 0.5, 0.5],
10+
"darkgray": [0.25, 0.25, 0.25],
11+
"black": [0, 0, 0],
12+
#
13+
"red": [1, 0, 0],
14+
"green": [0, 1, 0],
15+
"blue": [0, 0, 1],
16+
"brown": [0.75, 0.5, 0.25],
17+
"lime": [0.75, 1, 0],
18+
"orange": [1, 0.5, 0],
19+
"pink": [1, 0.75, 0.75],
20+
"purple": [0.75, 0, 0.25],
21+
"teal": [0, 0.5, 0.5],
22+
"violet": [0.5, 0, 0.5],
23+
# The colors cyan, magenta, yellow, and olive are also
24+
# predefined by xcolor, but their RGB approximation of the
25+
# native CMYK values is not very good. Don't use them here.
26+
}
27+
28+
29+
def _get_closest_colour_name(rgb):
30+
match = None
31+
mindiff = 1.0e15
32+
for h, name in webcolors.CSS3_HEX_TO_NAMES.items():
33+
r = int(h[1:3], 16)
34+
g = int(h[3:5], 16)
35+
b = int(h[5:7], 16)
36+
37+
diff = (rgb[0] - r) ** 2 + (rgb[1] - g) ** 2 + (rgb[2] - b) ** 2
38+
if diff < mindiff:
39+
match = name
40+
mindiff = diff
41+
42+
if mindiff == 0:
43+
break
44+
45+
return match, mindiff
346

447

548
def mpl_color2xcolor(data, matplotlib_color):
@@ -12,66 +55,30 @@ def mpl_color2xcolor(data, matplotlib_color):
1255
if my_col[-1] == 0.0:
1356
return data, "none", my_col
1457

15-
xcol = None
16-
# RGB values (as taken from xcolor.dtx):
17-
available_colors = {
18-
# List white first such that for gray values, the combination
19-
# white!<x>!black is preferred over, e.g., gray!<y>!black. Note that
20-
# the order of the dictionary is respected from Python 3.6 on.
21-
"white": np.array([1, 1, 1]),
22-
"lightgray": np.array([0.75, 0.75, 0.75]),
23-
"gray": np.array([0.5, 0.5, 0.5]),
24-
"darkgray": np.array([0.25, 0.25, 0.25]),
25-
"black": np.array([0, 0, 0]),
26-
#
27-
"red": np.array([1, 0, 0]),
28-
"green": np.array([0, 1, 0]),
29-
"blue": np.array([0, 0, 1]),
30-
"brown": np.array([0.75, 0.5, 0.25]),
31-
"lime": np.array([0.75, 1, 0]),
32-
"orange": np.array([1, 0.5, 0]),
33-
"pink": np.array([1, 0.75, 0.75]),
34-
"purple": np.array([0.75, 0, 0.25]),
35-
"teal": np.array([0, 0.5, 0.5]),
36-
"violet": np.array([0.5, 0, 0.5]),
37-
# The colors cyan, magenta, yellow, and olive are also
38-
# predefined by xcolor, but their RGB approximation of the
39-
# native CMYK values is not very good. Don't use them here.
40-
}
41-
42-
available_colors.update(data["custom colors"])
43-
4458
# Check if it exactly matches any of the colors already available.
4559
# This case is actually treated below (alpha==1), but that loop
4660
# may pick up combinations with black before finding the exact
4761
# match. Hence, first check all colors.
48-
for name, rgb in available_colors.items():
62+
for name, rgb in builtin_colors.items():
4963
if all(my_col[:3] == rgb):
50-
xcol = name
51-
return data, xcol, my_col
64+
return data, name, my_col
5265

53-
# Check if my_col is a multiple of a predefined color and 'black'.
54-
for name, rgb in available_colors.items():
55-
if name == "black":
56-
continue
66+
# Don't handle gray colors separately. They can be specified in xcolor as
67+
#
68+
# {gray}{0.6901960784313725}
69+
#
70+
# but this float representation hides the fact that this is actually an
71+
# RGB255 integer value, 176.
5772

58-
if rgb[0] != 0.0:
59-
alpha = my_col[0] / rgb[0]
60-
elif rgb[1] != 0.0:
61-
alpha = my_col[1] / rgb[1]
62-
else:
63-
assert rgb[2] != 0.0
64-
alpha = my_col[2] / rgb[2]
73+
# convert to RGB255
74+
rgb255 = np.array(my_col[:3] * 255, dtype=int)
6575

66-
# The cases 0.0 (my_col == black) and 1.0 (my_col == rgb) are
67-
# already accounted for by checking in available_colors above.
68-
if all(my_col[:3] == alpha * rgb) and 0.0 < alpha < 1.0:
69-
ff = data["float format"]
70-
xcol = name + f"!{alpha*100:{ff}}!black"
71-
return data, xcol, my_col
72-
73-
# Lookup failed, add it to the custom list.
74-
xcol = "color" + str(len(data["custom colors"]))
75-
data["custom colors"][xcol] = my_col[:3]
76+
name, diff = _get_closest_colour_name(rgb255)
77+
if diff > 0:
78+
if np.all(my_col[0] == my_col[:3]):
79+
name = f"{name}{rgb255[0]}"
80+
else:
81+
name = f"{name}{rgb255[0]}{rgb255[1]}{rgb255[2]}"
82+
data["custom colors"][name] = ("RGB", ",".join([str(val) for val in rgb255]))
7683

77-
return data, xcol, my_col
84+
return data, name, my_col

src/tikzplotlib/_save.py

+5-3
Original file line numberDiff line numberDiff line change
@@ -271,10 +271,12 @@ def _tex_comment(comment):
271271

272272
def _get_color_definitions(data):
273273
"""Returns the list of custom color definitions for the TikZ file."""
274-
ff = data["float format"]
274+
# sort by key
275+
sorted_keys = sorted(data["custom colors"].keys(), key=lambda x: x.lower())
276+
d = {key: data["custom colors"][key] for key in sorted_keys}
275277
return [
276-
f"\\definecolor{{{name}}}{{rgb}}{{{rgb[0]:{ff}},{rgb[1]:{ff}},{rgb[2]:{ff}}}}"
277-
for name, rgb in data["custom colors"].items()
278+
f"\\definecolor{{{name}}}{{{space}}}{{{val}}}"
279+
for name, (space, val) in d.items()
278280
]
279281

280282

0 commit comments

Comments
 (0)