diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2527ba9a..9afc7fa7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,7 +23,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.7", "3.8", "3.9", "3.10-dev"] + python-version: ["3.7", "3.8", "3.9", "3.10"] steps: - uses: actions/setup-python@v2 with: diff --git a/README.md b/README.md index e9b1b771..e98fd56e 100644 --- a/README.md +++ b/README.md @@ -30,9 +30,9 @@ The output of tikzplotlib is in [PGFPlots](https://github.com/pgf-tikz/pgfplots/ library that sits on top of [PGF/TikZ](https://en.wikipedia.org/wiki/PGF/TikZ) and describes graphs in terms of axes, data etc. Consequently, the output of tikzplotlib -- retains more information, -- can be more easily understood, and -- is more easily editable +- retains more information, +- can be more easily understood, and +- is more easily editable than [raw TikZ output](https://matplotlib.org/users/whats_new.html#pgf-tikz-backend). For example, the matplotlib figure diff --git a/setup.cfg b/setup.cfg index 3fc16dc5..fb5e7dac 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = tikzplotlib -version = 0.9.14 +version = 0.9.15 author = Nico Schlömer author_email = nico.schloemer@gmail.com description = Convert matplotlib figures into TikZ/PGFPlots diff --git a/src/tikzplotlib/_axes.py b/src/tikzplotlib/_axes.py index 2109b4d9..15605935 100644 --- a/src/tikzplotlib/_axes.py +++ b/src/tikzplotlib/_axes.py @@ -541,6 +541,7 @@ def _get_tick_position(obj, axes_obj): if len(set(major_ticks_top)) == 1 and major_ticks_top[0] is True: major_ticks_top_show_all = True + position_string = None major_ticks_position = None if not major_ticks_bottom_show_all and not major_ticks_top_show_all: position_string = f"{axes_obj}majorticks=false" @@ -562,27 +563,39 @@ def _get_ticks(data, xy, ticks, ticklabels): necessary axis options for the given configuration. """ axis_options = [] - pgfplots_ticks = [] - pgfplots_ticklabels = [] + + # Check if the label is necessary. If one of the labels is, then all of them must + # appear in the TikZ plot. is_label_required = False for tick, ticklabel in zip(ticks, ticklabels): # store the label anyway label = ticklabel.get_text() - if "," in label: - label = "{" + label + "}" - if ticklabel.get_visible(): - label = _common_texification(label) - pgfplots_ticklabels.append(label) - else: + + if not ticklabel.get_visible(): is_label_required = True - # Check if the label is necessary. If one of the labels is, then all of them - # must appear in the TikZ plot. - if label: - try: - label_float = float(label.replace("\N{MINUS SIGN}", "-")) - is_label_required = is_label_required or (label and label_float != tick) - except ValueError: + break + + if not label: + continue + + try: + label_float = float(label.replace("\N{MINUS SIGN}", "-")) + except ValueError: + is_label_required = True + break + else: + if abs(label_float - tick) > 1.0e-10 + 1.0e-10 * abs(tick): is_label_required = True + break + + pgfplots_ticks = [] + pgfplots_ticklabels = [] + for tick, ticklabel in zip(ticks, ticklabels): + label = ticklabel.get_text() + if "," in label: + label = "{" + label + "}" + pgfplots_ticklabels.append(_common_texification(label)) + # note: ticks may be present even if labels are not, keep them for grid lines for tick in ticks: pgfplots_ticks.append(tick) diff --git a/src/tikzplotlib/_path.py b/src/tikzplotlib/_path.py index dc717c73..0d2fa28b 100644 --- a/src/tikzplotlib/_path.py +++ b/src/tikzplotlib/_path.py @@ -407,44 +407,27 @@ def get_draw_options(data, obj, ec, fc, ls, lw, hatch=None): def mpl_linewidth2pgfp_linewidth(data, line_width): - if data["strict"]: - # Takes the matplotlib linewidths, and just translate them into PGFPlots. - try: - return { - 0.1: "ultra thin", - 0.2: "very thin", - 0.4: "thin", - 0.6: "semithick", - 0.8: "thick", - 1.2: "very thick", - 1.6: "ultra thick", - }[line_width] - except KeyError: - # explicit line width - ff = data["float format"] - return f"line width={line_width:{ff}}pt" - - # The following is an alternative approach to line widths. - # The default line width in matplotlib is 1.0pt, in PGFPlots 0.4pt - # ('thin'). - # Match the two defaults, and scale for the rest. - scaled_line_width = line_width / 1.0 # scale by default line width + # PGFplots gives line widths in pt, matplotlib in axes space. Translate. + # Scale such that the default mpl line width (1.5) is mapped to the PGFplots + # line with semithick, 0.6. From a visual comparison, semithick or even thick + # matches best with the default mpl style. + # Keep the line with in units of decipoint to make sure we stay in integers. + line_width_decipoint = line_width * 4 # 4 = 10 * 0.6 / 1.5 try: - out = { - 0.25: "ultra thin", - 0.5: "very thin", - 1.0: None, # default, 'thin' - 1.5: "semithick", - 2: "thick", - 3: "very thick", - 4: "ultra thick", - }[scaled_line_width] + # https://github.com/pgf-tikz/pgf/blob/e9c22dc9fe48f975b7fdb32181f03090b3747499/tex/generic/pgf/frontendlayer/tikz/tikz.code.tex#L1574 + return { + 1: "ultra thin", + 2: "very thin", + 4: None, # "thin", + 6: "semithick", + 8: "thick", + 12: "very thick", + 16: "ultra thick", + }[line_width_decipoint] except KeyError: # explicit line width ff = data["float format"] - out = f"line width={0.4 * line_width:{ff}}pt" - - return out + return f"line width={line_width_decipoint / 10:{ff}}pt" def mpl_linestyle2pgfplots_linestyle(data, line_style, line=None): diff --git a/tests/test_barchart_errorbars_reference.tex b/tests/test_barchart_errorbars_reference.tex index 33e955bd..f2065e62 100644 --- a/tests/test_barchart_errorbars_reference.tex +++ b/tests/test_barchart_errorbars_reference.tex @@ -55,37 +55,37 @@ (axis cs:2.25,0.9) --(axis cs:2.25,1.1); -\addplot [semithick, black, mark=-, mark size=8, mark options={solid}, only marks] +\addplot [line width=2pt, black, mark=-, mark size=8, mark options={solid}, only marks] table {% -0.25 0.9 0.75 1.8 1.75 2.5 }; -\addplot [semithick, black, mark=-, mark size=8, mark options={solid}, only marks] +\addplot [line width=2pt, black, mark=-, mark size=8, mark options={solid}, only marks] table {% -0.25 1.1 0.75 2.2 1.75 3.5 }; -\addplot [semithick, black, mark=-, mark size=8, mark options={solid}, only marks] +\addplot [line width=2pt, black, mark=-, mark size=8, mark options={solid}, only marks] table {% 0 2.6 1 1.8 2 3.5 }; -\addplot [semithick, black, mark=-, mark size=8, mark options={solid}, only marks] +\addplot [line width=2pt, black, mark=-, mark size=8, mark options={solid}, only marks] table {% 0 3.4 1 2.2 2 4.5 }; -\addplot [semithick, black, mark=-, mark size=8, mark options={solid}, only marks] +\addplot [line width=2pt, black, mark=-, mark size=8, mark options={solid}, only marks] table {% 0.25 4.9 1.25 2.8 2.25 0.9 }; -\addplot [semithick, black, mark=-, mark size=8, mark options={solid}, only marks] +\addplot [line width=2pt, black, mark=-, mark size=8, mark options={solid}, only marks] table {% 0.25 5.1 1.25 3.2 diff --git a/tests/test_cleanfigure.py b/tests/test_cleanfigure.py index ae8a43e4..6a501706 100644 --- a/tests/test_cleanfigure.py +++ b/tests/test_cleanfigure.py @@ -174,7 +174,7 @@ def test_surface3D(self): with plt.rc_context(rc=RC_PARAMS): fig = plt.figure() - ax = fig.gca(projection="3d") + ax = plt.axes(projection="3d") # Plot the surface. surf = ax.plot_surface( @@ -217,7 +217,7 @@ def test_trisurface3D(self): with plt.rc_context(rc=RC_PARAMS): fig = plt.figure() - ax = fig.gca(projection="3d") + ax = plt.axes(projection="3d") ax.plot_trisurf(x, y, z, linewidth=0.2, antialiased=True) with pytest.warns(Warning): @@ -244,7 +244,7 @@ def test_polygon3D(self): with plt.rc_context(rc=RC_PARAMS): fig = plt.figure() - ax = fig.gca(projection="3d") + ax = plt.axes(projection="3d") def cc(arg): """ @@ -302,7 +302,7 @@ def test_bar3D(self): def test_quiver3D(self): with plt.rc_context(rc=RC_PARAMS): fig = plt.figure() - ax = fig.gca(projection="3d") + ax = plt.axes(projection="3d") # Make the grid x, y, z = np.meshgrid( @@ -328,8 +328,7 @@ def test_quiver3D(self): def test_2D_in_3D(self): with plt.rc_context(rc=RC_PARAMS): - fig = plt.figure() - ax = fig.gca(projection="3d") + ax = plt.axes(projection="3d") # Plot a sin curve using the x and y axes. x = np.linspace(0, 1, 100) diff --git a/tests/test_colorbars_reference.tex b/tests/test_colorbars_reference.tex index d97d8841..1708a934 100644 --- a/tests/test_colorbars_reference.tex +++ b/tests/test_colorbars_reference.tex @@ -19,18 +19,9 @@ --(axis cs:9.9414062,10) --(axis cs:-4.9414062,10) --(axis cs:-5,10) ---cycle; -\addplot graphics [includegraphics cmd=\pgfimage,xmin=-5, xmax=10, ymin=-5, ymax=10] {tmp-000.png}; -\path [draw=black, line width=0.32pt] -(axis cs:-5,-5) ---(axis cs:-4.9414062,-5) ---(axis cs:9.9414062,-5) ---(axis cs:10,-5) ---(axis cs:10,10) ---(axis cs:9.9414062,10) ---(axis cs:-4.9414062,10) --(axis cs:-5,10) --cycle; +\addplot graphics [includegraphics cmd=\pgfimage,xmin=-5, xmax=10, ymin=-5, ymax=10] {tmp-000.png}; \nextgroupplot[ tick align=outside, @@ -39,8 +30,6 @@ xlabel={Discrete intervals, some other units}, xmin=0.65, xmax=8.35, xtick style={color=black}, -xtick={1,2,4,7,8}, -xticklabels={1,2,4,7,8}, ymin=1, ymax=8 ] \path [draw=white, fill=white, line width=0.004pt] @@ -54,16 +43,6 @@ --(axis cs:0.65,4.5) --cycle; \addplot graphics [includegraphics cmd=\pgfimage,xmin=0.65, xmax=8.35, ymin=1, ymax=8] {tmp-001.png}; -\path [draw=black, line width=0.32pt] -(axis cs:0.65,4.5) ---(axis cs:1,1) ---(axis cs:8,1) ---(axis cs:8.35,4.5) ---(axis cs:8.35,4.5) ---(axis cs:8,8) ---(axis cs:1,8) ---(axis cs:0.65,4.5) ---cycle; \nextgroupplot[ tick align=outside, @@ -85,16 +64,6 @@ --(axis cs:-1.5,0) --cycle; \addplot graphics [includegraphics cmd=\pgfimage,xmin=-1.5, xmax=1.5, ymin=-1, ymax=1] {tmp-002.png}; -\path [draw=black, line width=0.32pt] -(axis cs:-1.5,0) ---(axis cs:-1,-1) ---(axis cs:1,-1) ---(axis cs:1.5,0) ---(axis cs:1.5,0) ---(axis cs:1,1) ---(axis cs:-1,1) ---(axis cs:-1.5,0) ---cycle; \end{groupplot} \end{tikzpicture} diff --git a/tests/test_fillstyle_reference.tex b/tests/test_fillstyle_reference.tex index 410e0191..3e27c83e 100644 --- a/tests/test_fillstyle_reference.tex +++ b/tests/test_fillstyle_reference.tex @@ -8,8 +8,6 @@ x grid style={white!69.019608!black}, xmin=-0.05, xmax=1.05, xtick style={color=black}, -xtick={-0.2,0,0.2,0.4,0.6,0.8,1,1.2}, -xticklabels={−0.2,0.0,0.2,0.4,0.6,0.8,1.0,1.2}, y grid style={white!69.019608!black}, ymin=-0.45, ymax=9.45, ytick style={color=black} diff --git a/tox.ini b/tox.ini index f1ca5478..189dbf81 100644 --- a/tox.ini +++ b/tox.ini @@ -8,7 +8,7 @@ deps = pytest pytest-cov pytest-codeblocks - matplotlib == 3.3.4 + matplotlib == 3.4.3 pytest-randomly commands = pytest {posargs} --codeblocks