Skip to content

Commit

Permalink
Merge pull request #534 from nschloe/new-mpl
Browse files Browse the repository at this point in the history
update test mpl version
  • Loading branch information
nschloe authored Jan 31, 2022
2 parents fe5dcf5 + c3bb690 commit 06b498e
Show file tree
Hide file tree
Showing 83 changed files with 977 additions and 938 deletions.
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ repos:
- id: isort

- repo: https://github.com/psf/black
rev: 21.12b0
rev: 22.1.0
hooks:
- id: black
language_version: python3
Expand Down
17 changes: 4 additions & 13 deletions justfile
Original file line number Diff line number Diff line change
@@ -1,21 +1,12 @@
version := `python3 -c "from configparser import ConfigParser; p = ConfigParser(); p.read('setup.cfg'); print(p['metadata']['version'])"`
name := `python3 -c "from configparser import ConfigParser; p = ConfigParser(); p.read('setup.cfg'); print(p['metadata']['name'])"`

version := `python3 -c "from src.tikzplotlib.__about__ import __version__; print(__version__)"`

default:
@echo "\"just publish\"?"

tag:
@if [ "$(git rev-parse --abbrev-ref HEAD)" != "main" ]; then exit 1; fi
curl -H "Authorization: token `cat ~/.github-access-token`" -d '{"tag_name": "v{{version}}"}' https://api.github.com/repos/nschloe/{{name}}/releases

upload: clean
publish:
@if [ "$(git rev-parse --abbrev-ref HEAD)" != "main" ]; then exit 1; fi
# https://stackoverflow.com/a/58756491/353337
python3 -m build --sdist --wheel .
twine upload dist/*

publish: tag upload
gh release create "v{{version}}"
flit publish

clean:
@find . | grep -E "(__pycache__|\.pyc|\.pyo$)" | xargs rm -rf
Expand Down
39 changes: 37 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,41 @@
[build-system]
requires = ["setuptools>=42", "wheel"]
build-backend = "setuptools.build_meta"
requires = ["flit_core >=3.2,<4"]
build-backend = "flit_core.buildapi"

[tool.isort]
profile = "black"

[project]
name = "tikzplotlib"
authors = [{name = "Nico Schlömer", email = "[email protected]"}]
description = "Convert matplotlib figures into TikZ/PGFPlots"
readme = "README.md"
license = {file = "LICENSE"}
classifiers = [
"Development Status :: 5 - Production/Stable",
"Framework :: Matplotlib",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
"Programming Language :: Python",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Topic :: Multimedia :: Graphics :: Graphics Conversion",
"Topic :: Scientific/Engineering :: Visualization",
]
keywords = ["latex", "tikz", "matplotlib", "graphics"]
dynamic = ["version"]
requires-python = ">=3.7"
dependencies = [
"matplotlib >= 1.4.0",
"numpy",
"Pillow",
"webcolors",
]

[project.urls]
Code = "https://github.com/nschloe/tikzplotlib"
Issues = "https://github.com/nschloe/tikzplotlib/issues"
Funding = "https://github.com/sponsors/nschloe"
47 changes: 0 additions & 47 deletions setup.cfg

This file was deleted.

11 changes: 1 addition & 10 deletions src/tikzplotlib/__about__.py
Original file line number Diff line number Diff line change
@@ -1,10 +1 @@
try:
# Python 3.8
from importlib import metadata
except ImportError:
import importlib_metadata as metadata

try:
__version__ = metadata.version("tikzplotlib")
except Exception:
__version__ = "unknown"
__version__ = "0.10.0"
16 changes: 11 additions & 5 deletions src/tikzplotlib/_axes.py
Original file line number Diff line number Diff line change
Expand Up @@ -630,13 +630,19 @@ def _get_ticks(data, xy, ticks, ticklabels):

def _is_colorbar_heuristic(obj):
"""Find out if the object is in fact a color bar."""
# TODO come up with something more accurate here
# Not sure if these properties are always present
if hasattr(obj, "_colorbar") or hasattr(obj, "_colorbar_info"):
return True

# TODO come up with something more accurate here. See
# <https://discourse.matplotlib.org/t/find-out-if-an-axes-object-is-a-colorbar/22563>
# Might help:
# TODO Are the colorbars exactly the l.collections.PolyCollection's?

try:
aspect = float(obj.get_aspect())
except ValueError:
# e.g., aspect == 'equal'
# e.g., aspect in ['equal', 'auto']
return False

# Assume that something is a colorbar if and only if the ratio is above 5.0
Expand All @@ -646,10 +652,10 @@ def _is_colorbar_heuristic(obj):
#
# plt.colorbar(im, aspect=5)
#
limit_ratio = 5.0
threshold_ratio = 5.0

return (aspect >= limit_ratio and len(obj.get_xticks()) == 0) or (
aspect <= 1.0 / limit_ratio and len(obj.get_yticks()) == 0
return (aspect >= threshold_ratio and len(obj.get_xticks()) == 0) or (
aspect <= 1.0 / threshold_ratio and len(obj.get_yticks()) == 0
)


Expand Down
115 changes: 61 additions & 54 deletions src/tikzplotlib/_color.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,48 @@
import matplotlib as mpl
import numpy as np
import webcolors

# RGB values (as taken from xcolor.dtx):
builtin_colors = {
"white": [1, 1, 1],
"lightgray": [0.75, 0.75, 0.75],
"gray": [0.5, 0.5, 0.5],
"darkgray": [0.25, 0.25, 0.25],
"black": [0, 0, 0],
#
"red": [1, 0, 0],
"green": [0, 1, 0],
"blue": [0, 0, 1],
"brown": [0.75, 0.5, 0.25],
"lime": [0.75, 1, 0],
"orange": [1, 0.5, 0],
"pink": [1, 0.75, 0.75],
"purple": [0.75, 0, 0.25],
"teal": [0, 0.5, 0.5],
"violet": [0.5, 0, 0.5],
# The colors cyan, magenta, yellow, and olive are also
# predefined by xcolor, but their RGB approximation of the
# native CMYK values is not very good. Don't use them here.
}


def _get_closest_colour_name(rgb):
match = None
mindiff = 1.0e15
for h, name in webcolors.CSS3_HEX_TO_NAMES.items():
r = int(h[1:3], 16)
g = int(h[3:5], 16)
b = int(h[5:7], 16)

diff = (rgb[0] - r) ** 2 + (rgb[1] - g) ** 2 + (rgb[2] - b) ** 2
if diff < mindiff:
match = name
mindiff = diff

if mindiff == 0:
break

return match, mindiff


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

xcol = None
# RGB values (as taken from xcolor.dtx):
available_colors = {
# List white first such that for gray values, the combination
# white!<x>!black is preferred over, e.g., gray!<y>!black. Note that
# the order of the dictionary is respected from Python 3.6 on.
"white": np.array([1, 1, 1]),
"lightgray": np.array([0.75, 0.75, 0.75]),
"gray": np.array([0.5, 0.5, 0.5]),
"darkgray": np.array([0.25, 0.25, 0.25]),
"black": np.array([0, 0, 0]),
#
"red": np.array([1, 0, 0]),
"green": np.array([0, 1, 0]),
"blue": np.array([0, 0, 1]),
"brown": np.array([0.75, 0.5, 0.25]),
"lime": np.array([0.75, 1, 0]),
"orange": np.array([1, 0.5, 0]),
"pink": np.array([1, 0.75, 0.75]),
"purple": np.array([0.75, 0, 0.25]),
"teal": np.array([0, 0.5, 0.5]),
"violet": np.array([0.5, 0, 0.5]),
# The colors cyan, magenta, yellow, and olive are also
# predefined by xcolor, but their RGB approximation of the
# native CMYK values is not very good. Don't use them here.
}

available_colors.update(data["custom colors"])

# Check if it exactly matches any of the colors already available.
# This case is actually treated below (alpha==1), but that loop
# may pick up combinations with black before finding the exact
# match. Hence, first check all colors.
for name, rgb in available_colors.items():
for name, rgb in builtin_colors.items():
if all(my_col[:3] == rgb):
xcol = name
return data, xcol, my_col
return data, name, my_col

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

if rgb[0] != 0.0:
alpha = my_col[0] / rgb[0]
elif rgb[1] != 0.0:
alpha = my_col[1] / rgb[1]
else:
assert rgb[2] != 0.0
alpha = my_col[2] / rgb[2]
# convert to RGB255
rgb255 = np.array(my_col[:3] * 255, dtype=int)

# The cases 0.0 (my_col == black) and 1.0 (my_col == rgb) are
# already accounted for by checking in available_colors above.
if all(my_col[:3] == alpha * rgb) and 0.0 < alpha < 1.0:
ff = data["float format"]
xcol = name + f"!{alpha*100:{ff}}!black"
return data, xcol, my_col

# Lookup failed, add it to the custom list.
xcol = "color" + str(len(data["custom colors"]))
data["custom colors"][xcol] = my_col[:3]
name, diff = _get_closest_colour_name(rgb255)
if diff > 0:
if np.all(my_col[0] == my_col[:3]):
name = f"{name}{rgb255[0]}"
else:
name = f"{name}{rgb255[0]}{rgb255[1]}{rgb255[2]}"
data["custom colors"][name] = ("RGB", ",".join([str(val) for val in rgb255]))

return data, xcol, my_col
return data, name, my_col
8 changes: 5 additions & 3 deletions src/tikzplotlib/_save.py
Original file line number Diff line number Diff line change
Expand Up @@ -271,10 +271,12 @@ def _tex_comment(comment):

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


Expand Down
Loading

0 comments on commit 06b498e

Please sign in to comment.