kopia lustrzana https://github.com/corrscope/corrscope
RendererConfig calculates orientation based on nrows or ncols.
- Ensure either nrows or ncols is set. - If neither, set ncols=1 (single column). - Remove rows_first flag. Add test_renderer.pypull/357/head
rodzic
8b71df0bbb
commit
2ad624be03
ovgenpy
tests
|
@ -50,7 +50,6 @@ def main(wave_dir: str, master_wave: Optional[str], fps: int):
|
|||
),
|
||||
render=RendererConfig( # todo
|
||||
1280, 720,
|
||||
rows_first=False,
|
||||
ncols=1
|
||||
)
|
||||
)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
from typing import NamedTuple, Optional, List, Tuple
|
||||
|
||||
import numpy as np
|
||||
from dataclasses import dataclass
|
||||
from matplotlib import pyplot as plt
|
||||
from matplotlib.axes import Axes
|
||||
from matplotlib.figure import Figure
|
||||
|
@ -9,21 +10,29 @@ from matplotlib.lines import Line2D
|
|||
from ovgenpy.util import ceildiv
|
||||
|
||||
|
||||
class RendererConfig(NamedTuple):
|
||||
@dataclass
|
||||
class RendererConfig:
|
||||
width: int
|
||||
height: int
|
||||
|
||||
rows_first: bool
|
||||
|
||||
nrows: Optional[int] = None # TODO set to 1
|
||||
nrows: Optional[int] = None
|
||||
ncols: Optional[int] = None
|
||||
|
||||
# TODO backend: FigureCanvasBase = FigureCanvasAgg
|
||||
def __post_init__(self):
|
||||
if not self.nrows:
|
||||
self.nrows = None
|
||||
if not self.ncols:
|
||||
self.ncols = None
|
||||
|
||||
if self.nrows and self.ncols:
|
||||
raise ValueError('cannot manually assign both nrows and ncols')
|
||||
|
||||
if not self.nrows and not self.ncols:
|
||||
self.ncols = 1
|
||||
|
||||
|
||||
class MatplotlibRenderer:
|
||||
"""
|
||||
TODO disable antialiasing
|
||||
If __init__ reads cfg, cfg cannot be hotswapped.
|
||||
|
||||
Reasons to hotswap cfg: RendererCfg:
|
||||
|
@ -48,6 +57,8 @@ class MatplotlibRenderer:
|
|||
self.fig: Figure = None
|
||||
|
||||
# Setup layout
|
||||
# "ncols=1" is good for vertical layouts.
|
||||
# But "nrows=X" is good for left-to-right grids.
|
||||
|
||||
self.nrows = 0
|
||||
self.ncols = 0
|
||||
|
@ -60,13 +71,14 @@ class MatplotlibRenderer:
|
|||
|
||||
def set_layout(self) -> None:
|
||||
"""
|
||||
Inputs: self.cfg, self.waves, self.fig
|
||||
Outputs: self.nrows, self.ncols, self.axes
|
||||
|
||||
Creates a flat array of Matplotlib Axes, with the new layout.
|
||||
Opens a window showing the Figure (and Axes).
|
||||
|
||||
Inputs: self.cfg, self.fig
|
||||
Outputs: self.nrows, self.ncols, self.axes
|
||||
"""
|
||||
|
||||
self.nrows, self.ncols = self.calc_layout()
|
||||
self.nrows, self.ncols = self._calc_layout()
|
||||
|
||||
# Create Axes
|
||||
# https://matplotlib.org/api/_as_gen/matplotlib.pyplot.subplots.html
|
||||
|
@ -86,7 +98,7 @@ class MatplotlibRenderer:
|
|||
ax.set_axis_off()
|
||||
|
||||
# if column major:
|
||||
if not self.cfg.rows_first:
|
||||
if self.cfg.ncols:
|
||||
axes2d = axes2d.T
|
||||
|
||||
self.axes: List[Axes] = axes2d.flatten().tolist()[:self.nplots]
|
||||
|
@ -99,14 +111,14 @@ class MatplotlibRenderer:
|
|||
)
|
||||
plt.show(block=False)
|
||||
|
||||
def calc_layout(self) -> Tuple[int, int]:
|
||||
def _calc_layout(self) -> Tuple[int, int]:
|
||||
"""
|
||||
Inputs: self.cfg, self.waves
|
||||
:return: (nrows, ncols)
|
||||
"""
|
||||
cfg = self.cfg
|
||||
|
||||
if cfg.rows_first:
|
||||
if cfg.nrows:
|
||||
nrows = cfg.nrows
|
||||
if nrows is None:
|
||||
raise ValueError('invalid cfg: rows_first is True and nrows is None')
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
from matplotlib import pyplot as plt
|
||||
|
||||
from ovgenpy.renderer import RendererConfig, MatplotlibRenderer
|
||||
|
||||
|
||||
WIDTH = 640
|
||||
HEIGHT = 360
|
||||
|
||||
def test_config():
|
||||
with pytest.raises(ValueError):
|
||||
RendererConfig(WIDTH, HEIGHT, nrows=1, ncols=1)
|
||||
|
||||
one_col = RendererConfig(WIDTH, HEIGHT, ncols=1)
|
||||
assert one_col
|
||||
|
||||
one_row = RendererConfig(WIDTH, HEIGHT, nrows=1)
|
||||
assert one_row
|
||||
|
||||
default = RendererConfig(WIDTH, HEIGHT)
|
||||
assert default.ncols == 1 # Should default to single-column layout
|
||||
assert default.nrows is None
|
||||
|
||||
|
||||
@patch("ovgenpy.renderer.plt.show")
|
||||
def test_renderer(mock_show):
|
||||
"""
|
||||
TODO check image output using:
|
||||
https://matplotlib.org/devel/testing.html#writing-an-image-comparison-test
|
||||
|
||||
https://stackoverflow.com/a/27950953
|
||||
"[I]mage comparison tests end up bring more trouble than they are worth"
|
||||
"""
|
||||
# monkeypatch.setattr(plt, 'show', lambda *args, **kwargs: None)
|
||||
|
||||
# 2 columns
|
||||
cfg = RendererConfig(WIDTH, HEIGHT, ncols=2)
|
||||
nplots = 16
|
||||
|
||||
r = MatplotlibRenderer(cfg, nplots)
|
||||
|
||||
# 2 columns, 8 rows
|
||||
assert r.ncols == 2
|
||||
assert r.nrows == 8
|
Ładowanie…
Reference in New Issue