|
1 |
| -import pytest |
2 |
| -from tikzplotlib import cleanfigure |
3 | 1 | import numpy as np
|
| 2 | +import pytest |
4 | 3 | from matplotlib import pyplot as plt
|
5 | 4 |
|
| 5 | +from tikzplotlib import cleanfigure |
| 6 | + |
6 | 7 | RC_PARAMS = {"figure.figsize": [5, 5], "figure.dpi": 220, "pgf.rcfonts": False}
|
7 | 8 |
|
8 | 9 |
|
@@ -159,3 +160,252 @@ def test_interactiveManipulation():
|
159 | 160 | l.set_ydata(data[:, 1])
|
160 | 161 | plt.show()
|
161 | 162 |
|
| 163 | + |
| 164 | +def test_movePointsCloser(): |
| 165 | + """ |
| 166 | + octave code |
| 167 | + ```octave |
| 168 | + addpath ("../matlab2tikz/src") |
| 169 | +
|
| 170 | + x = linspace(1, 100, 20); |
| 171 | + y1 = linspace(1, 100, 20); |
| 172 | +
|
| 173 | + figure |
| 174 | + plot(x, y1) |
| 175 | + xlim([20, 80]) |
| 176 | + ylim([20, 80]) |
| 177 | + set(gcf,'Units','Inches'); |
| 178 | + set(gcf,'Position',[2.5 2.5 5 5]) |
| 179 | + cleanfigure; |
| 180 | + ``` |
| 181 | + """ |
| 182 | + x = np.linspace(1, 100, 20) |
| 183 | + y = np.linspace(1, 100, 20) |
| 184 | + |
| 185 | + with plt.rc_context(rc=RC_PARAMS): |
| 186 | + fig, ax = plt.subplots(1, 1, figsize=(5, 5)) |
| 187 | + (l,) = ax.plot(x, y) |
| 188 | + ax.set_ylim([20, 80]) |
| 189 | + ax.set_xlim([20, 80]) |
| 190 | + cleanfigure.pruneOutsideBox(fig, ax, l) |
| 191 | + cleanfigure.movePointscloser(fig, ax, l) |
| 192 | + assert l.get_xdata().shape == (14,) |
| 193 | + |
| 194 | + |
| 195 | +def test_simplifyLine(): |
| 196 | + """ |
| 197 | + octave code |
| 198 | + ```octave |
| 199 | + addpath ("../matlab2tikz/src") |
| 200 | +
|
| 201 | + x = linspace(1, 100, 20); |
| 202 | + y1 = linspace(1, 100, 20); |
| 203 | +
|
| 204 | + figure |
| 205 | + plot(x, y1) |
| 206 | + xlim([20, 80]) |
| 207 | + ylim([20, 80]) |
| 208 | + set(gcf,'Units','Inches'); |
| 209 | + set(gcf,'Position',[2.5 2.5 5 5]) |
| 210 | + cleanfigure; |
| 211 | + ``` |
| 212 | + """ |
| 213 | + x = np.linspace(1, 100, 20) |
| 214 | + y = np.linspace(1, 100, 20) |
| 215 | + |
| 216 | + with plt.rc_context(rc=RC_PARAMS): |
| 217 | + fig, ax = plt.subplots(1, 1, figsize=(5, 5)) |
| 218 | + (l,) = ax.plot(x, y) |
| 219 | + ax.set_ylim([20, 80]) |
| 220 | + ax.set_xlim([20, 80]) |
| 221 | + cleanfigure.pruneOutsideBox(fig, ax, l) |
| 222 | + cleanfigure.movePointscloser(fig, ax, l) |
| 223 | + cleanfigure.simplifyLine(fig, ax, l, 600) |
| 224 | + assert l.get_xdata().shape == (2,) |
| 225 | + assert l.get_ydata().shape == (2,) |
| 226 | + |
| 227 | + |
| 228 | +def test_limitPrecision(): |
| 229 | + """ |
| 230 | + octave code |
| 231 | + ```octave |
| 232 | + addpath ("../matlab2tikz/src") |
| 233 | +
|
| 234 | + x = linspace(1, 100, 20); |
| 235 | + y1 = linspace(1, 100, 20); |
| 236 | +
|
| 237 | + figure |
| 238 | + plot(x, y1) |
| 239 | + xlim([20, 80]) |
| 240 | + ylim([20, 80]) |
| 241 | + set(gcf,'Units','Inches'); |
| 242 | + set(gcf,'Position',[2.5 2.5 5 5]) |
| 243 | + cleanfigure; |
| 244 | + ``` |
| 245 | + """ |
| 246 | + x = np.linspace(1, 100, 20) |
| 247 | + y = np.linspace(1, 100, 20) |
| 248 | + |
| 249 | + with plt.rc_context(rc=RC_PARAMS): |
| 250 | + fig, ax = plt.subplots(1, 1, figsize=(5, 5)) |
| 251 | + (l,) = ax.plot(x, y) |
| 252 | + ax.set_ylim([20, 80]) |
| 253 | + ax.set_xlim([20, 80]) |
| 254 | + cleanfigure.pruneOutsideBox(fig, ax, l) |
| 255 | + cleanfigure.movePointscloser(fig, ax, l) |
| 256 | + cleanfigure.simplifyLine(fig, ax, l, 600) |
| 257 | + cleanfigure.limitPrecision(fig, ax, l, 1) |
| 258 | + assert l.get_xdata().shape == (2,) |
| 259 | + assert l.get_ydata().shape == (2,) |
| 260 | + |
| 261 | + |
| 262 | +def test_opheimSimplify(): |
| 263 | + """test path simplification |
| 264 | +
|
| 265 | + octave code |
| 266 | + ```octave |
| 267 | + addpath ("../matlab2tikz/src") |
| 268 | +
|
| 269 | + x = linspace(1, 100, 20); |
| 270 | + y1 = linspace(1, 100, 20); |
| 271 | +
|
| 272 | + figure |
| 273 | + plot(x, y1) |
| 274 | + xlim([20, 80]) |
| 275 | + ylim([20, 80]) |
| 276 | + set(gcf,'Units','Inches'); |
| 277 | + set(gcf,'Position',[2.5 2.5 5 5]) |
| 278 | + cleanfigure; |
| 279 | + ``` |
| 280 | + """ |
| 281 | + x = np.array( |
| 282 | + [ |
| 283 | + 21.842106, |
| 284 | + 27.052631, |
| 285 | + 32.263157, |
| 286 | + 37.473682, |
| 287 | + 42.68421, |
| 288 | + 47.894737, |
| 289 | + 53.105263, |
| 290 | + 58.31579, |
| 291 | + 63.526318, |
| 292 | + 68.73684, |
| 293 | + 73.947365, |
| 294 | + 79.1579, |
| 295 | + ] |
| 296 | + ) |
| 297 | + y = x.copy() |
| 298 | + tol = 0.02 |
| 299 | + mask = cleanfigure.opheimSimplify(x, y, tol) |
| 300 | + assert mask.shape == (12,) |
| 301 | + assert np.allclose(mask * 1, np.array([1,] + [0,] * 10 + [1,])) |
| 302 | + |
| 303 | + |
| 304 | +# TODO: test for getVisualData |
| 305 | + |
| 306 | + |
| 307 | +def test_cleanfigure(): |
| 308 | + """test high-level usage for simple example. |
| 309 | + Test is successfull if generated tikz code saves correct amount of lines |
| 310 | + """ |
| 311 | + from tikzplotlib import get_tikz_code |
| 312 | + |
| 313 | + x = np.linspace(1, 100, 20) |
| 314 | + y = np.linspace(1, 100, 20) |
| 315 | + |
| 316 | + with plt.rc_context(rc=RC_PARAMS): |
| 317 | + fig, ax = plt.subplots(1, 1, figsize=(5, 5)) |
| 318 | + ax.plot(x, y) |
| 319 | + ax.set_ylim([20, 80]) |
| 320 | + ax.set_xlim([20, 80]) |
| 321 | + raw = get_tikz_code() |
| 322 | + |
| 323 | + cleanfigure.cleanfigure(fig, ax) |
| 324 | + clean = get_tikz_code() |
| 325 | + |
| 326 | + # Use number of lines to test if it worked. |
| 327 | + # the baseline (raw) should have 20 points |
| 328 | + # the clean version (clean) should have 2 points |
| 329 | + # the difference in line numbers should therefore be 2 |
| 330 | + numLinesRaw = raw.count("\n") |
| 331 | + numLinesClean = clean.count("\n") |
| 332 | + assert numLinesRaw - numLinesClean == 18 |
| 333 | + |
| 334 | + |
| 335 | +def test_segmentVisible(): |
| 336 | + """test against matlab2tikz implementation |
| 337 | +
|
| 338 | + octave code to generate baseline results. Note that octave has indexing 1...N, whereas python has indexing 0...N-1. |
| 339 | + ```octave |
| 340 | + x = linspace(1, 100, 20); |
| 341 | + y1 = linspace(1, 100, 20); |
| 342 | +
|
| 343 | + figure |
| 344 | + plot(x, y1) |
| 345 | + xlim([20, 80]) |
| 346 | + ylim([20, 80]) |
| 347 | + cleanfigure; |
| 348 | + ``` |
| 349 | + """ |
| 350 | + |
| 351 | + y = np.linspace(1, 100, 20) |
| 352 | + x = y.copy() |
| 353 | + data = np.stack([x, y], axis=1) |
| 354 | + dataIsInBox = np.array([0,] * 4 + [1,] * 12 + [0,] * 4) == 1 |
| 355 | + xLim = np.array([20, 80]) |
| 356 | + yLim = np.array([20, 80]) |
| 357 | + mask = cleanfigure.segmentVisible(data, dataIsInBox, xLim, yLim) |
| 358 | + assert np.allclose(mask * 1, np.array([0,] * 3 + [1,] * 13 + [0,] * 3)) |
| 359 | + |
| 360 | + |
| 361 | +def test_crossLines(): |
| 362 | + """test against matplotlib2tikz implementation |
| 363 | + """ |
| 364 | + y = np.linspace(1, 100, 20) |
| 365 | + x = y.copy() |
| 366 | + data = np.stack([x, y], axis=1) |
| 367 | + X1 = data[:-1, :] |
| 368 | + X2 = data[1:, :] |
| 369 | + X3 = np.array([80, 20]) |
| 370 | + X4 = np.array([80, 80]) |
| 371 | + Lambda = cleanfigure.crossLines(X1, X2, X3, X4) |
| 372 | + |
| 373 | + expected_result = np.array( |
| 374 | + [ |
| 375 | + [15.16162, 1.00000], |
| 376 | + [14.16162, 1.00000], |
| 377 | + [13.16162, 1.00000], |
| 378 | + [12.16162, 1.00000], |
| 379 | + [11.16162, 1.00000], |
| 380 | + [10.16162, 1.00000], |
| 381 | + [9.16162, 1.00000], |
| 382 | + [8.16162, 1.00000], |
| 383 | + [7.16162, 1.00000], |
| 384 | + [6.16162, 1.00000], |
| 385 | + [5.16162, 1.00000], |
| 386 | + [4.16162, 1.00000], |
| 387 | + [3.16162, 1.00000], |
| 388 | + [2.16162, 1.00000], |
| 389 | + [1.16162, 1.00000], |
| 390 | + [0.16162, 1.00000], |
| 391 | + [-0.83838, 1.00000], |
| 392 | + [-1.83838, 1.00000], |
| 393 | + [-2.83838, 1.00000], |
| 394 | + ] |
| 395 | + ) |
| 396 | + assert np.allclose(Lambda, expected_result, rtol=1.0e-4) |
| 397 | + |
| 398 | + |
| 399 | +def test_segmentsIntersect(): |
| 400 | + """test against matplotlib2tikz implementation |
| 401 | + """ |
| 402 | + y = np.linspace(1, 100, 20) |
| 403 | + x = y.copy() |
| 404 | + data = np.stack([x, y], axis=1) |
| 405 | + X1 = data[:-1, :] |
| 406 | + X2 = data[1:, :] |
| 407 | + X3 = np.array([80, 20]) |
| 408 | + X4 = np.array([80, 80]) |
| 409 | + mask = cleanfigure.segmentsIntersect(X1, X2, X3, X4) |
| 410 | + assert np.allclose(mask * 1, np.zeros_like(mask)) |
| 411 | + |
0 commit comments