Skip to content

Commit f5c5ee7

Browse files
authored
Merge pull request #466 from nschloe/horizontal-alignment
Horizontal alignment
2 parents 778ea4a + d676207 commit f5c5ee7

9 files changed

+131
-83
lines changed

setup.cfg

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[metadata]
22
name = tikzplotlib
3-
version = 0.9.7
3+
version = 0.9.8
44
author = Nico Schlömer
55
author_email = [email protected]
66
description = Convert matplotlib figures into TikZ/PGFPlots
@@ -21,6 +21,7 @@ classifiers =
2121
Programming Language :: Python :: 3.6
2222
Programming Language :: Python :: 3.7
2323
Programming Language :: Python :: 3.8
24+
Programming Language :: Python :: 3.9
2425
Topic :: Multimedia :: Graphics :: Graphics Conversion
2526
Topic :: Scientific/Engineering :: Visualization
2627
keywords =

test/test_dual_axis_reference.tex

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,8 @@
4848
y grid style={white!69.019608!black},
4949
ymin=-100, ymax=2100,
5050
ytick pos=right,
51-
ytick style={color=black}
51+
ytick style={color=black},
52+
yticklabel style={anchor=west}
5253
]
5354
\addplot [semithick, color0]
5455
table {%

test/test_horizontal_alignment.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import numpy as np
2+
import matplotlib.pyplot as plt
3+
4+
from helpers import assert_equality
5+
6+
7+
def plot():
8+
labels = ["lab1", "label 2", "another super label"]
9+
n = len(labels)
10+
x = np.arange(n)
11+
y = 1 / (x + 1)
12+
13+
ax = plt.gca()
14+
ax.bar(x, y, 0.5)
15+
16+
ax.set_xticks(x)
17+
ax.set_xticklabels(labels)
18+
plt.xticks(rotation=45, ha="right")
19+
20+
21+
def test():
22+
assert_equality(plot, "test_horizontal_alignment_reference.tex")
23+
24+
25+
if __name__ == "__main__":
26+
# import helpers
27+
# helpers.compare_mpl_tex(plot)
28+
plot()
29+
plt.show()
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
\begin{tikzpicture}
2+
3+
\definecolor{color0}{rgb}{0.12156863,0.46666667,0.70588235}
4+
5+
\begin{axis}[
6+
tick align=outside,
7+
tick pos=left,
8+
x grid style={white!69.019608!black},
9+
xmin=-0.375, xmax=2.375,
10+
xtick style={color=black},
11+
xtick={0,1,2},
12+
xticklabel style={rotate=45.0,anchor=east},
13+
xticklabels={lab1,label 2,another super label},
14+
y grid style={white!69.019608!black},
15+
ymin=0, ymax=1.05,
16+
ytick style={color=black}
17+
]
18+
\draw[draw=none,fill=color0] (axis cs:-0.25,0) rectangle (axis cs:0.25,1);
19+
\draw[draw=none,fill=color0] (axis cs:0.75,0) rectangle (axis cs:1.25,0.5);
20+
\draw[draw=none,fill=color0] (axis cs:1.75,0) rectangle (axis cs:2.25,0.33333333);
21+
\end{axis}
22+
23+
\end{tikzpicture}

test/test_legend_best_location.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import matplotlib.pyplot as plt
22
import numpy as np
3+
import pytest
4+
35
from helpers import assert_equality
46

57

@@ -58,9 +60,10 @@ def plot():
5860
return fig
5961

6062

63+
# TODO find a way to make this robust
64+
@pytest.mark.skip(reason="'Best' location depends on window size.")
6165
def test():
6266
assert_equality(plot, "test_legend_best_location_reference.tex")
63-
return
6467

6568

6669
if __name__ == "__main__":

test/test_legend_best_location_reference.tex

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,8 @@
4747
fill opacity=0.8,
4848
draw opacity=1,
4949
text opacity=1,
50-
at={(0.03,0.97)},
51-
anchor=north west,
50+
at={(0.5,0.91)},
51+
anchor=north,
5252
draw=white!80!black
5353
},
5454
scaled x ticks=manual:{}{\pgfmathparse{#1}},
@@ -135,8 +135,8 @@
135135
fill opacity=0.8,
136136
draw opacity=1,
137137
text opacity=1,
138-
at={(0.03,0.03)},
139-
anchor=south west,
138+
at={(0.97,0.03)},
139+
anchor=south east,
140140
draw=white!80!black
141141
},
142142
scaled x ticks=manual:{}{\pgfmathparse{#1}},
@@ -239,8 +239,8 @@
239239
fill opacity=0.8,
240240
draw opacity=1,
241241
text opacity=1,
242-
at={(0.09,0.5)},
243-
anchor=west,
242+
at={(0.5,0.5)},
243+
anchor=center,
244244
draw=white!80!black
245245
},
246246
scaled x ticks=manual:{}{\pgfmathparse{#1}},
@@ -321,8 +321,8 @@
321321
fill opacity=0.8,
322322
draw opacity=1,
323323
text opacity=1,
324-
at={(0.5,0.09)},
325-
anchor=south,
324+
at={(0.97,0.03)},
325+
anchor=south east,
326326
draw=white!80!black
327327
},
328328
tick align=outside,
@@ -357,14 +357,7 @@
357357

358358
\nextgroupplot[
359359
legend cell align={left},
360-
legend style={
361-
fill opacity=0.8,
362-
draw opacity=1,
363-
text opacity=1,
364-
at={(0.5,0.91)},
365-
anchor=north,
366-
draw=white!80!black
367-
},
360+
legend style={fill opacity=0.8, draw opacity=1, text opacity=1, draw=white!80!black},
368361
scaled y ticks=manual:{}{\pgfmathparse{#1}},
369362
tick align=outside,
370363
tick pos=left,
@@ -398,7 +391,14 @@
398391
\addlegendentry{UC}
399392

400393
\nextgroupplot[
401-
legend style={fill opacity=0.8, draw opacity=1, text opacity=1, draw=white!80!black},
394+
legend style={
395+
fill opacity=0.8,
396+
draw opacity=1,
397+
text opacity=1,
398+
at={(0.91,0.5)},
399+
anchor=east,
400+
draw=white!80!black
401+
},
402402
scaled y ticks=manual:{}{\pgfmathparse{#1}},
403403
tick align=outside,
404404
tick pos=left,

tikzplotlib/_axes.py

Lines changed: 47 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -459,69 +459,55 @@ def _get_label_rotation_and_horizontal_alignment(self, obj, data, x_or_y):
459459
if tick_label_text_width_identifier in self.axis_options:
460460
self.axis_options.remove(tick_label_text_width_identifier)
461461

462-
tick_labels_rotation = [label.get_rotation() for label in major_tick_labels]
463-
tick_labels_rotation_same_value = len(set(tick_labels_rotation)) == 1
464-
465-
tick_labels_horizontal_alignment = [
466-
label.get_horizontalalignment() for label in major_tick_labels
467-
]
468-
tick_labels_horizontal_alignment_same_value = (
469-
len(set(tick_labels_horizontal_alignment)) == 1
470-
)
462+
values = []
471463

472-
if (
473-
tick_labels_rotation_same_value
474-
and tick_labels_horizontal_alignment_same_value
475-
):
476-
values = []
477-
478-
if any(tick_labels_rotation) != 0:
464+
tick_labels_rotation = [label.get_rotation() for label in major_tick_labels]
465+
if len(set(tick_labels_rotation)) == 1:
466+
if tick_labels_rotation[0] != 0:
479467
values.append(f"rotate={tick_labels_rotation[0]}")
480-
481-
# Horizontal alignment will be ignored if no 'x/y tick label text width' has
482-
# been passed in the 'extra' parameter
483-
# tick_label_text_width = None
484-
# if tick_label_text_width:
485-
# values.append(f"align={tick_labels_horizontal_alignment[0]}")
486-
# values.append(f"text width={tick_label_text_width}")
487-
488-
if values:
489-
label_style = "{}ticklabel style = {{{}}}".format(
490-
x_or_y, ",".join(values)
491-
)
492468
else:
493-
values = []
494-
495-
if tick_labels_rotation_same_value:
496-
values.append("rotate={tick_labels_rotation[0]}")
497-
else:
498-
values.append(
499-
"rotate={{{},0}}[\\ticknum]".format(
500-
",".join(str(x) for x in tick_labels_rotation)
501-
)
469+
values.append(
470+
"rotate={{{},0}}[\\ticknum]".format(
471+
",".join(str(x) for x in tick_labels_rotation)
502472
)
503-
504-
# Ignore horizontal alignment if no '{x,y} tick label text width' has been
505-
# passed in the 'extra' parameter
506-
# if tick_label_text_width:
507-
# if tick_labels_horizontal_alignment_same_value:
508-
# values.append(f"align={tick_labels_horizontal_alignment[0]}")
509-
# values.append(f"text width={tick_label_text_width}")
510-
# else:
511-
# for idx, x in enumerate(tick_labels_horizontal_alignment):
512-
# label_style += f"{x_or_y}_tick_label_ha_{idx}/.initial = {x}"
513-
514-
# values.append(
515-
# f"align=\\pgfkeysvalueof{{/pgfplots/{x_or_y}_tick_label_ha_\\ticknum}}"
516-
# )
517-
# values.append(f"text width={tick_label_text_width}")
518-
519-
label_style = (
520-
"every {} tick label/.style = {{\n"
521-
"{}\n"
522-
"}}".format(x_or_y, ",\n".join(values))
523473
)
524474

475+
tick_labels_horizontal_alignment = [
476+
label.get_horizontalalignment() for label in major_tick_labels
477+
]
478+
if len(set(tick_labels_horizontal_alignment)) == 1:
479+
anchor = {"right": "east", "left": "west", "center": "center"}[
480+
tick_labels_horizontal_alignment[0]
481+
]
482+
if not (x_or_y == "x" and anchor == "center") and not (
483+
x_or_y == "y" and anchor == "east"
484+
):
485+
values.append(f"anchor={anchor}")
486+
487+
if values:
488+
label_style = "{}ticklabel style={{{}}}".format(x_or_y, ",".join(values))
489+
490+
# Ignore horizontal alignment if no '{x,y} tick label text width' has been
491+
# passed in the 'extra' parameter
492+
# if tick_label_text_width:
493+
# if is_tick_label_alignment_identical:
494+
# values.append(f"align={tick_labels_horizontal_alignment[0]}")
495+
# values.append(f"text width={tick_label_text_width}")
496+
# else:
497+
# for idx, x in enumerate(tick_labels_horizontal_alignment):
498+
# label_style += f"{x_or_y}_tick_label_ha_{idx}/.initial = {x}"
499+
500+
# values.append(
501+
# f"align=\\pgfkeysvalueof{{/pgfplots/{x_or_y}_tick_label_ha_\\ticknum}}"
502+
# )
503+
# values.append(f"text width={tick_label_text_width}")
504+
505+
# label_style = (
506+
# "every {} tick label/.style = {{\n"
507+
# "{}\n"
508+
# "}}".format(x_or_y, ",\n".join(values))
509+
# )
510+
525511
return label_style
526512

527513

@@ -606,9 +592,10 @@ def _get_ticks(data, xy, ticks, ticklabels):
606592
axis_options.append(f"{xy}tick={val}")
607593

608594
if is_label_required:
609-
axis_options.append(
610-
"{}ticklabels={{{}}}".format(xy, ",".join(pgfplots_ticklabels))
611-
)
595+
length = sum(len(label) for label in pgfplots_ticklabels)
596+
sep = ("", ",", "") if length < 75 else ("\n ", ",\n ", "\n")
597+
string = sep[1].join(pgfplots_ticklabels)
598+
axis_options.append(f"{xy}ticklabels={{{sep[0]}{string}{sep[2]}}}")
612599
return axis_options
613600

614601

tikzplotlib/_cleanfigure.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -569,8 +569,8 @@ def _get_line_data(linehandle):
569569
xData, yData, zData = linehandle.get_data_3d()
570570
data = _stack_data_3D(xData, yData, zData)
571571
else:
572-
xData = linehandle.get_xdata().astype(np.float32)
573-
yData = linehandle.get_ydata().astype(np.float32)
572+
xData = np.asarray(linehandle.get_xdata()).astype(np.float32)
573+
yData = np.asarray(linehandle.get_ydata()).astype(np.float32)
574574
data = _stack_data_2D(xData, yData)
575575
return data, is3D
576576

tikzplotlib/_save.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ def get_tikz_code(
3131
extra_axis_parameters: Optional[Union[List, Set]] = None,
3232
extra_groupstyle_parameters: dict = {},
3333
extra_tikzpicture_parameters: Optional[Union[List, Set]] = None,
34+
extra_lines_start: Optional[Union[List, Set]] = None,
3435
dpi: Optional[int] = None,
3536
show_info: bool = False,
3637
include_disclaimer: bool = True,
@@ -224,7 +225,10 @@ def get_tikz_code(
224225
code += data["flavor"].start("tikzpicture")
225226
if extra_tikzpicture_parameters:
226227
code += "[\n" + ",\n".join(extra_tikzpicture_parameters) + "\n]"
227-
code += "\n\n"
228+
code += "\n"
229+
if extra_lines_start:
230+
code += "\n".join(extra_lines_start) + "\n"
231+
code += "\n"
228232

229233
coldefs = _get_color_definitions(data)
230234
if coldefs:

0 commit comments

Comments
 (0)