Skip to content

Commit e445b12

Browse files
committed
Naming and docs cleanup
1 parent 35e2132 commit e445b12

File tree

1 file changed

+73
-77
lines changed

1 file changed

+73
-77
lines changed

tikzplotlib/_hatches.py

Lines changed: 73 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,26 @@
1-
import warnings
1+
r"""
2+
Map matplotlib hatches to tikz patterns
3+
4+
For matplotlib hatches, see:
5+
https://matplotlib.org/3.1.1/gallery/shapes_and_collections/hatch_demo.html
26
3-
# From https://matplotlib.org/3.1.1/api/_as_gen/matplotlib.patches.Patch.html:
4-
# > Letters can be combined, in which case all the specified hatchings are done.
5-
# > If same letter repeats, it increases the density of hatching of that pattern.
6-
# To achieve something like this, custom patterns must be created
7-
# https://tex.stackexchange.com/questions/29359/pgfplots-how-to-fill-the-area-under-a-curve-with-oblique-lines-hatching-as-a/29367#29367
7+
For patterns in tikzpgf:
8+
Ch 26 Pattern Lbrary in the manual
9+
Requires \usetikzlibrary{patterns}
10+
"""
811

9-
# These methods exist, and might be relevant:
12+
# These methods exist, and might be relevant (in the future?):
1013
# matplotlib.backend_bases.GraphicsContextBase.set/get_hatch_color
1114
# matplotlib.backend_bases.GraphicsContextBase.set/get_hatch_linewidth
1215
# hatch_density is mentioned in mpl API Changes in 2.0.1
1316

14-
# for matplotlib hatches, see:
15-
# https://matplotlib.org/3.1.1/gallery/shapes_and_collections/hatch_demo.html
1617

17-
# hatches in tikzpgf: Ch 26 Pattern Lbrary with \usetikzlibrary{patterns}
18+
import warnings
19+
1820

1921
BAD_MP_HATCH = ["o", "O"] # Bad hatch/pattern correspondance
20-
UNUSED_PGF_HATCH = ["dots"]
21-
_MP_HATCH2PGF_HATCH = {
22+
UNUSED_PGF_PATTERN = ["dots"]
23+
_MP_HATCH2PGF_PATTERN = {
2224
"-": "horizontal lines",
2325
"|": "vertical lines",
2426
"/": "north east lines",
@@ -32,89 +34,83 @@
3234
}
3335

3436

35-
def add_custom_pattern(mpl_hatch, pattern_name, pattern_definition):
36-
pass
37+
def add_custom_pattern(mpl_hatch, pattern_name, pattern_definition=None):
38+
"""
39+
The patterns of tikzpgf are quite simple, and cannot be customized but for the
40+
color. A solution is to expose a function like this one to allow the user to
41+
populate _MP_HATCH2PGF_PATTERN with custom (hatch, pattern) pairs. mpl does no
42+
validation of the hatch string, it just ignores it if it does not recognize it,
43+
so it is possible to have <any> string be a mpl_hatch.
44+
45+
If the pattern definition is passed, it could be added at the start of the code
46+
in a similar fashion to
47+
> data["custom colors"] = {}
48+
in get_tikz_code(). tikzplotlib pattern definitions would mend the bad
49+
correspondence between the mpl hatches and tikz patterns, with custom patterns
50+
for the mpl hatches 'o' and 'O'
51+
52+
Want some opinions on this before I implement it..
53+
54+
From https://matplotlib.org/3.1.1/api/_as_gen/matplotlib.patches.Patch.html:
55+
> Letters can be combined, in which case all the specified hatchings are done.
56+
> If same letter repeats, it increases the density of hatching of that pattern.
57+
To achieve something like this, custom patterns must be created
58+
https://tex.stackexchange.com/questions/29359/pgfplots-how-to-fill-the-area-
59+
under-a-curve-with-oblique-lines-hatching-as-a/29367#29367
60+
"""
3761

3862

39-
def __validate_mpl_hatch(mpl_hatch):
40-
if len(mpl_hatch) > 1:
63+
def __validate_hatch(hatch):
64+
""" Warn about the shortcomings of patterns """
65+
if len(hatch) > 1:
4166
warnings.warn(
42-
f"tikzplotlib: Hatch '{mpl_hatch}' cannot be rendered. "
67+
f"tikzplotlib: Hatch '{hatch}' cannot be rendered. "
4368
+ "Only single character hatches are supported, e.g., "
4469
+ r"{'/', '\', '|', '-', '+', 'x', 'o', 'O', '.', '*'}. "
45-
+ f"Hatch '{mpl_hatch[0]}' will be used."
70+
+ f"Hatch '{hatch[0]}' will be used."
4671
)
47-
mpl_hatch = mpl_hatch[0]
72+
hatch = hatch[0]
4873

49-
if mpl_hatch in BAD_MP_HATCH:
74+
if hatch in BAD_MP_HATCH:
5075
warnings.warn(
5176
f"tikzplotlib: The hatches {BAD_MP_HATCH} do not have good PGF"
5277
+ " counterparts."
5378
)
54-
return mpl_hatch
79+
return hatch
5580

5681

57-
def _mpl_hatch2pgfp_hatch(data, mpl_hatch, color_name, color_rgba):
58-
"""
59-
Translates a hatch style of matplotlib to the corresponding style
60-
in PGFPlots.
82+
def _mpl_hatch2pgfp_pattern(data, hatch, color_name, color_rgba):
83+
r"""
84+
Translates a hatch from matplotlib to the corresponding patten in PGFPlots.
85+
86+
Input:
87+
hatch - str, like {'/', '\', '|', '-', '+', 'x', 'o', 'O', '.', '*'}
88+
color_name - str, xcolor or custom color name
89+
color_rgba - np.array, the rgba value of the color
90+
Output:
91+
draw_options - list, empty or with a post action string
6192
"""
6293
data["tikz libs"].add("patterns")
6394

64-
mpl_hatch = __validate_mpl_hatch(mpl_hatch)
95+
hatch = __validate_hatch(hatch)
6596
try:
66-
pgfplots_hatch = _MP_HATCH2PGF_HATCH.get(mpl_hatch)
97+
pgfplots_pattern = _MP_HATCH2PGF_PATTERN.get(hatch)
6798
except KeyError:
68-
warnings.warn("tikzplotlib: The hatch", mpl_hatch, "cannot be handled.")
99+
warnings.warn("tikzplotlib: The hatch", hatch, "is ignored.")
69100
return data, []
70-
else:
71-
pattern_options = [f"pattern={pgfplots_hatch}"]
72-
if color_name != "black":
73-
# PGFPlots render patterns in 'pattern color' (default: black)
74-
pattern_options += [f"pattern color={color_name}"]
75-
if color_rgba[3] != 1:
76-
ff = data["float format"]
77-
# PGFPlots render patterns according to opacity fill.
78-
pattern_options.append(("fill opacity=" + ff).format(color_rgba[3]))
79-
80-
# Add pattern as postaction to allow fill and pattern
101+
102+
pattern_options = [f"pattern={pgfplots_pattern}"]
103+
if color_name != "black":
104+
# PGFPlots render patterns in 'pattern color' (default: black)
105+
pattern_options += [f"pattern color={color_name}"]
106+
if color_rgba[3] != 1:
107+
ff = data["float format"]
108+
# PGFPlots render patterns according to opacity fill.
109+
pattern_options.append(("fill opacity=" + ff).format(color_rgba[3]))
110+
111+
# Add pattern as postaction to allow color fill and pattern together
81112
# https://tex.stackexchange.com/questions/24964/
82113
# how-to-combine-fill-and-pattern-in-a-pgfplot-bar-plot
83-
hatch_postaction = f"postaction={{{', '.join(pattern_options)}}}"
84-
85-
return data, [hatch_postaction]
86-
87-
88-
if __name__ == "__main__":
89-
import warnings
90-
import matplotlib.pyplot as plt
91-
import matplotlib
92-
93-
fig, ax = plt.subplots()
94-
95-
ax.bar(range(1, 5), range(1, 5), color="red", edgecolor="black", hatch="O")
96-
97-
for c in ax.get_children():
98-
try:
99-
hatch = c.get_hatch()
100-
except AttributeError as error:
101-
pass
102-
else:
103-
if hatch is not None:
104-
print(c, hatch)
105-
try:
106-
color = c.get_hatch_color()
107-
except AttributeError as error:
108-
pass
109-
else:
110-
if color is not None:
111-
print(c, color)
112-
try:
113-
lw = c.get_hatch_linewidth()
114-
except AttributeError as error:
115-
pass
116-
else:
117-
if lw is not None:
118-
print(c, lw)
119-
120-
plt.show()
114+
postaction = f"postaction={{{', '.join(pattern_options)}}}"
115+
116+
return data, [postaction]

0 commit comments

Comments
 (0)