Skip to content

Commit

Permalink
LIN-189 Test matplotlib examples (LineaLabs#628)
Browse files Browse the repository at this point in the history
* Test dash_joinstyle.py example

* Test aliased.py example

* Test exercice_3.py example

* Test alpha.py example

* Remove unnecessary file

* Directly version-control scripts that were tested

Original submodule (https://github.com/rougier/matplotlib-tutorial.git) relies on outdated matplotlib version, so many of its examples do not work. We may want to use materials in official matplotlib repo. In the mean time, remove this outdated submodule, but keep its scripts that could be tested (by directly version-controlling them).

Co-authored-by: Yifan Wu <yifan1030@gmail.com>
  • Loading branch information
yoonspark and yifanwu committed May 4, 2022
1 parent 89243a7 commit 2c09587
Show file tree
Hide file tree
Showing 16 changed files with 395 additions and 9 deletions.
2 changes: 2 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,12 @@
[submodule "tests/integration/sources/tensorflow-decision-forests"]
path = tests/integration/sources/tensorflow-decision-forests
url = git@github.com:tensorflow/decision-forests.git
ignore = all
[submodule "tests/integration/sources/xgboost"]
path = tests/integration/sources/xgboost
url = git@github.com:dmlc/xgboost.git
ignore = all
[submodule "tests/integration/sources/pandas_exercises"]
path = tests/integration/sources/pandas_exercises
url = git@github.com:guipsamora/pandas_exercises.git
ignore = all
78 changes: 78 additions & 0 deletions lineapy/external.annotations.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -183,3 +183,81 @@
- views:
- self_ref: SELF_REF
- result: RESULT
- module: matplotlib.pyplot
annotations:
- criteria:
function_names:
- plot
- boxplot
- xlim
- xticks
- ylim
- yticks
- axvline
- axes
- text
side_effects:
- mutated_value:
self_ref: SELF_REF
- criteria:
function_names:
- figure
- subplot
side_effects:
- mutated_value:
self_ref: SELF_REF
- views:
- self_ref: SELF_REF
- result: RESULT
- criteria:
function_name: savefig
side_effects:
- mutated_value:
external_state: file_system
- module: matplotlib.figure
annotations:
- criteria:
class_instance: Figure
class_method_names:
- gca
- add_axes
- add_subplot
side_effects:
- mutated_value:
self_ref: SELF_REF
- views:
- self_ref: SELF_REF
- result: RESULT
- criteria:
class_instance: Figure
class_method_name: savefig
side_effects:
- mutated_value:
external_state: file_system
- module: matplotlib.patches
annotations:
- criteria:
class_instance: Rectangle
class_method_name: set_alpha
side_effects:
- mutated_value:
self_ref: SELF_REF
- module: matplotlib.axes._subplots
annotations:
- criteria:
class_instance: SubplotBase
class_method_names:
- axvline
- set_xticks
- set_xlim
- set_xlabel
- set_yticks
- set_ylim
- set_ylabel
- invert_yaxis
- set_title
- bar_label
- plot
side_effects:
- mutated_value:
self_ref: SELF_REF
39 changes: 30 additions & 9 deletions tests/integration/README.md
Original file line number Diff line number Diff line change
@@ -1,28 +1,49 @@
# Integration tests

This folder contains a number of "integration" tests, meaning tests of running files from third party sources unchanged, as a way to check Lineapy's validity against real world use cases.
This folder contains a number of "integration" tests, meaning tests of running
files from third party sources unchanged, as a way to check Lineapy's validity
against real world use cases.

## What the tests do

All of the tests so far of the same form, so they are all parameters of the same test function `test_slice.py::test_slice`.
All of the tests so far of the same form, so they are all parameters of the
same test function `test_slice.py::test_slice`.

In each the test:

1. Creates a conda environment for the project we are testing against in `envs/<virtualenv name>`, if that directory does not exist. Inside this environment, we install a development build of lineapy as well as any requirements needed to run the tests.
2. Load the hand written ground truth slice of the file from the `slices/<test id>.py` directory. If one does not exist, it will create one from the source file. Also prettify the file and save it back, to remove comments unneccesary spaces.
1. Creates a conda environment for the project we are testing against in `envs/<virtualenv name>`,
if that directory does not exist. Inside this environment, we install a
development build of lineapy as well as any requirements needed to run the tests.
2. Load the hand written ground truth slice of the file from the `slices/<test id>.py`
directory. If one does not exist, it will create one from the source file. Also
prettify the file and save it back, to remove comments unnecessary spaces.
3. Run the ground truth slice, to make sure that it is accurate.
4. Run the lineapy CLI on the source file (in `sources/`) to create a slice of it.
5. Verifies that that slice is equal to the snapshot (we make a snapshot of the slice, even if its "wrong", so that we can see in the the repo what the current slice is, and we can see how it changes over time, even if it is never fully "correct")
5. Verifies that that slice is equal to the snapshot (we make a snapshot of the
slice, even if its "wrong", so that we can see in the the repo what the current
slice is, and we can see how it changes over time, even if it is never fully "correct").
Note that a copy of the entire file will be created when it's run the first time,
and you can manually correct the slices, which will _not_ be overwritten in
future runs.
6. Assert that the created slice is equal to the ground truth slice, after prettifying each.

## Running tests

The tests have the `integration` mark so that they are not run by default. So to run them use `-m integration`.
The tests have the `integration` mark so that they are not run by default. So
to run them use `-m integration`.

Also, all the tests which have failing slices, are currently marked as xfailed, so will not raise errors by default. If you do want to see the errors, you can use `--runxfail` and use `-vv` to print out the full diff.
Note that when you run the tests for the first time in your environment, it might
take a long time (e.g., > 5 min), but future runs will be faster.

Most tests do succeed in producing a slice, but the slice just happens to be wrong, so they are marked with `raises=AssertionError`. This is so that pytest knows they should only fail there, not at an earlier step. However,
some tests don't succeed in even producing a slice, and those are just marked `xfail` without a reason.
Also, all the tests which have failing slices, are currently marked as xfailed,
so will not raise errors by default. If you do want to see the errors, you can
use `--runxfail` and use `-vv` to print out the full diff.

Most tests do succeed in producing a slice, but the slice just happens to be
wrong, so they are marked with `raises=AssertionError`. This is so that pytest
knows they should only fail there, not at an earlier step. However,
some tests don't succeed in even producing a slice, and those are just marked
`xfail` without a reason.

So if you wanted to say run the `numpy-mnist` test to see how the written slice
differs from the generated slice, you could do:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import matplotlib.pyplot as plt

size = 128, 16
dpi = 72.0
figsize = size[0] / float(dpi), size[1] / float(dpi)
fig = plt.figure(figsize=figsize, dpi=dpi)
plt.axes([0, 0, 1, 1], frameon=False)
plt.text(0.5, 0.5, "Aliased", ha="center", va="center")
plt.xlim(0, 1), plt.ylim(0, 1)
plt.xticks([]), plt.yticks([])
plt.savefig("../figures/aliased.png", dpi=dpi)
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import matplotlib.pyplot as plt
import numpy as np

size = 256, 16
dpi = 72.0
figsize = size[0] / float(dpi), size[1] / float(dpi)
fig = plt.figure(figsize=figsize, dpi=dpi)
plt.axes([0, 0, 1, 1], frameon=False)
plt.plot(
np.arange(3),
[0, 1, 0],
color="blue",
dashes=[12, 5],
linewidth=8,
dash_joinstyle="miter",
)
plt.plot(
4 + np.arange(3),
[0, 1, 0],
color="blue",
dashes=[12, 5],
linewidth=8,
dash_joinstyle="bevel",
)
plt.plot(
8 + np.arange(3),
[0, 1, 0],
color="blue",
dashes=[12, 5],
linewidth=8,
dash_joinstyle="round",
)
plt.xlim(0, 12), plt.ylim(-1, 2)
plt.xticks([]), plt.yticks([])
plt.savefig("../figures/dash_joinstyle.png", dpi=dpi)
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import matplotlib.pyplot as plt
import numpy as np

plt.figure(figsize=(8, 5), dpi=80)
plt.subplot(111)
X = np.linspace(-np.pi, np.pi, 256, endpoint=True)
C, S = np.cos(X), np.sin(X)
plt.plot(X, C, color="blue", linewidth=2.5, linestyle="-")
plt.plot(X, S, color="red", linewidth=2.5, linestyle="-")
plt.xlim(-4.0, 4.0)
plt.xticks(np.linspace(-4, 4, 9, endpoint=True))
plt.ylim(-1.0, 1.0)
plt.yticks(np.linspace(-1, 1, 5, endpoint=True))
linea_artifact_value = plt.gcf()
21 changes: 21 additions & 0 deletions tests/integration/slices/matplotlib_aliased.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# This is the manual slice of:
# lineapy.file_system
# from file:
# sources/matplotlib-tutorial/scripts/aliased.py

# To verify that linea produces the same slice, run:
# pytest -m integration --runxfail -vv 'tests/integration/test_slice.py::test_slice[matplotlib_aliased]'

import matplotlib.pyplot as plt

size = 128, 16
dpi = 72.0
figsize = size[0] / float(dpi), size[1] / float(dpi)
fig = plt.figure(figsize=figsize, dpi=dpi)
fig.patch.set_alpha(0)
plt.axes([0, 0, 1, 1], frameon=False)
plt.rcParams["text.antialiased"] = False
plt.text(0.5, 0.5, "Aliased", ha="center", va="center")
plt.xlim(0, 1), plt.ylim(0, 1)
plt.xticks([]), plt.yticks([])
plt.savefig("../figures/aliased.png", dpi=dpi)
21 changes: 21 additions & 0 deletions tests/integration/slices/matplotlib_alpha.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# This is the manual slice of:
# lineapy.file_system
# from file:
# sources/matplotlib-tutorial/scripts/alpha.py

# To verify that linea produces the same slice, run:
# pytest -m integration --runxfail -vv 'tests/integration/test_slice.py::test_slice[matplotlib_alpha]'

import matplotlib.pyplot as plt

size = 256, 16
dpi = 72.0
figsize = size[0] / float(dpi), size[1] / float(dpi)
fig = plt.figure(figsize=figsize, dpi=dpi)
fig.patch.set_alpha(0)
plt.axes([0, 0.1, 1, 0.8], frameon=False)
for i in range(1, 11):
plt.axvline(i, linewidth=1, color="blue", alpha=0.25 + 0.75 * i / 10.0)
plt.xlim(0, 11)
plt.xticks([]), plt.yticks([])
plt.savefig("../figures/alpha.png", dpi=dpi)
44 changes: 44 additions & 0 deletions tests/integration/slices/matplotlib_dash_joinstyle.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# This is the manual slice of:
# lineapy.file_system
# from file:
# sources/matplotlib-tutorial/scripts/dash_joinstyle.py

# To verify that linea produces the same slice, run:
# pytest -m integration --runxfail -vv 'tests/integration/test_slice.py::test_slice[matplotlib_dash_joinstyle]'

import matplotlib.pyplot as plt
import numpy as np

size = 256, 16
dpi = 72.0
figsize = size[0] / float(dpi), size[1] / float(dpi)
fig = plt.figure(figsize=figsize, dpi=dpi)
fig.patch.set_alpha(0)
plt.axes([0, 0, 1, 1], frameon=False)
plt.plot(
np.arange(3),
[0, 1, 0],
color="blue",
dashes=[12, 5],
linewidth=8,
dash_joinstyle="miter",
)
plt.plot(
4 + np.arange(3),
[0, 1, 0],
color="blue",
dashes=[12, 5],
linewidth=8,
dash_joinstyle="bevel",
)
plt.plot(
8 + np.arange(3),
[0, 1, 0],
color="blue",
dashes=[12, 5],
linewidth=8,
dash_joinstyle="round",
)
plt.xlim(0, 12), plt.ylim(-1, 2)
plt.xticks([]), plt.yticks([])
plt.savefig("../figures/dash_joinstyle.png", dpi=dpi)
22 changes: 22 additions & 0 deletions tests/integration/slices/matplotlib_exercise_3.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# This is the manual slice of:
# plt.gcf()
# from file:
# sources/matplotlib-tutorial/scripts/exercice_3.py

# To verify that linea produces the same slice, run:
# pytest -m integration --runxfail -vv 'tests/integration/test_slice.py::test_slice[matplotlib_exercise_3]'

import matplotlib.pyplot as plt
import numpy as np

plt.figure(figsize=(8, 5), dpi=80)
plt.subplot(111)
X = np.linspace(-np.pi, np.pi, 256, endpoint=True)
C, S = np.cos(X), np.sin(X)
plt.plot(X, C, color="blue", linewidth=2.5, linestyle="-")
plt.plot(X, S, color="red", linewidth=2.5, linestyle="-")
plt.xlim(-4.0, 4.0)
plt.xticks(np.linspace(-4, 4, 9, endpoint=True))
plt.ylim(-1.0, 1.0)
plt.yticks(np.linspace(-1, 1, 5, endpoint=True))
linea_artifact_value = plt.gcf()
Empty file.
16 changes: 16 additions & 0 deletions tests/integration/sources/matplotlib-tutorial/scripts/aliased.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import matplotlib.pyplot as plt

size = 128,16
dpi = 72.0
figsize= size[0]/float(dpi),size[1]/float(dpi)
fig = plt.figure(figsize=figsize, dpi=dpi)
fig.patch.set_alpha(0)
plt.axes([0,0,1,1], frameon=False)

plt.rcParams['text.antialiased'] = False
plt.text(0.5,0.5,"Aliased",ha='center',va='center')

plt.xlim(0,1),plt.ylim(0,1),
plt.xticks([]),plt.yticks([])

plt.savefig('../figures/aliased.png', dpi=dpi)
15 changes: 15 additions & 0 deletions tests/integration/sources/matplotlib-tutorial/scripts/alpha.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import matplotlib.pyplot as plt

size = 256,16
dpi = 72.0
figsize= size[0]/float(dpi),size[1]/float(dpi)
fig = plt.figure(figsize=figsize, dpi=dpi)
fig.patch.set_alpha(0)
plt.axes([0,0.1,1,.8], frameon=False)

for i in range(1,11):
plt.axvline(i, linewidth=1, color='blue',alpha=.25+.75*i/10.)

plt.xlim(0,11)
plt.xticks([]), plt.yticks([])
plt.savefig('../figures/alpha.png', dpi=dpi)
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import matplotlib.pyplot as plt
import numpy as np

size = 256,16
dpi = 72.0
figsize= size[0]/float(dpi),size[1]/float(dpi)
fig = plt.figure(figsize=figsize, dpi=dpi)
fig.patch.set_alpha(0)
plt.axes([0,0,1,1], frameon=False)

plt.plot(np.arange(3), [0,1,0], color="blue", dashes=[12,5], linewidth=8, dash_joinstyle = 'miter')
plt.plot(4+np.arange(3), [0,1,0], color="blue", dashes=[12,5], linewidth=8, dash_joinstyle = 'bevel')
plt.plot(8+np.arange(3), [0,1,0], color="blue", dashes=[12,5], linewidth=8, dash_joinstyle = 'round')

plt.xlim(0,12), plt.ylim(-1,2)
plt.xticks([]), plt.yticks([])

plt.savefig('../figures/dash_joinstyle.png', dpi=dpi)
#show()
Loading

0 comments on commit 2c09587

Please sign in to comment.