Squashed commit of the following:
commit e5832a17356cebd43846c0542ce595bba5a8cdda
Author: Matthias Bisping <matthias.bisping@axbit.com>
Date: Mon Feb 13 14:08:17 2023 +0100
reduce pytest parameter combinatons
commit a1e6c9e553545ed1fc4c017e67dddaa98fc2a1c9
Author: Matthias Bisping <matthias.bisping@axbit.com>
Date: Wed Feb 1 18:56:16 2023 +0100
clear color map cache per pytest parameter combination
commit 21a9db25cdb55b967c664f5d129a9ac35aa1da0f
Author: Matthias Bisping <matthias.bisping@axbit.com>
Date: Wed Feb 1 18:38:52 2023 +0100
Remove obsolete line
commit 90c367cc325dd3a4d3b8f7f37e06a79c30207867
Author: Matthias Bisping <matthias.bisping@axbit.com>
Date: Wed Feb 1 18:38:05 2023 +0100
Refactoring: Move
commit 42d285e35b82ba0f36835eff6ff70c50bd80d20c
Author: Matthias Bisping <matthias.bisping@axbit.com>
Date: Wed Feb 1 18:33:44 2023 +0100
Refactoring: Move
Move content generator into its own module
commit ddc92461d7442e08921408707ada6963f555f708
Author: Matthias Bisping <matthias.bisping@axbit.com>
Date: Wed Feb 1 18:29:59 2023 +0100
Refactoring: Move
Move remaining segment generation functions into segments module
commit d2cb78d38f47a8c705a82dd725e24c0540a29710
Author: Matthias Bisping <matthias.bisping@axbit.com>
Date: Wed Feb 1 18:27:26 2023 +0100
Refactoring: Move
Move zipmap and evert_nth into utils module
commit 9c401a977ce0749463cb2af509f412007f37a084
Author: Matthias Bisping <matthias.bisping@axbit.com>
Date: Wed Feb 1 18:26:01 2023 +0100
Refactoring: Move
Move rectangle shrinking logic into new morphing module
commit b77951d4feb1e5dacdb32f0d36a399f6f94b2293
Author: Matthias Bisping <matthias.bisping@axbit.com>
Date: Wed Feb 1 18:22:15 2023 +0100
Refactoring: Move
Move segment generation functions into their own module
commit c7b224a98a355f93653a0d576a10fbd2507ed1d8
Author: Matthias Bisping <matthias.bisping@axbit.com>
Date: Wed Feb 1 18:14:54 2023 +0100
Refactoring: Move
Move cell class into its own module
commit f0072b0852f34f0448d467fc4993eee3a23a6c5b
Author: Matthias Bisping <matthias.bisping@axbit.com>
Date: Wed Feb 1 18:12:18 2023 +0100
Refactoring: Move
Move table generation related code into new table module
commit 9fd87aff8ea69404959056b3d58c7f8856527c83
Author: Matthias Bisping <matthias.bisping@axbit.com>
Date: Wed Feb 1 18:07:36 2023 +0100
Refactoring: Move
- Move random plot into its own module
- Move geometric predicates into their own module
commit 6728642a4fc07ec9c47db99efe12981c18f95ee5
Author: Matthias Bisping <matthias.bisping@axbit.com>
Date: Wed Feb 1 17:59:54 2023 +0100
Refactoring: Move
Mode random helper functions
commit cc86a79ac7bc47e5ddb68e5c95327eebc97041d9
Author: Matthias Bisping <matthias.bisping@axbit.com>
Date: Wed Feb 1 17:33:51 2023 +0100
Refactoring: Move
Move text block generator module into text module
commit 160d5b3473d7e4f6f6dbb8fcf51cf554d6b54543
Author: Matthias Bisping <matthias.bisping@axbit.com>
Date: Wed Feb 1 17:29:29 2023 +0100
Remove unused code
commit 7b2f921472bb47b5c5d7848393ae471664eab583
Author: Matthias Bisping <matthias.bisping@axbit.com>
Date: Wed Feb 1 17:28:17 2023 +0100
Refactoring: Move
Move text block generators into their own module
commit e258df899f4be39beec4a0bfc01eaea105218adb
Author: Matthias Bisping <matthias.bisping@axbit.com>
Date: Wed Feb 1 17:24:54 2023 +0100
Refactoring: Move
Move text block into its own module
commit cef97b33f920488857c308e6ebcbc5a309de4b20
Author: Matthias Bisping <matthias.bisping@axbit.com>
Date: Wed Feb 1 17:20:30 2023 +0100
Refactoring: Move
Move page partitioners into partitioner module
commit a54ccb2fdf44595720718fef44d5d3b1b8cbfe0a
Author: Matthias Bisping <matthias.bisping@axbit.com>
Date: Wed Feb 1 17:15:40 2023 +0100
Refactoring: Move
Move text generation funtions into their own module
commit 1de938f2faa50cb805d7ebea3075c1d6d969d254
Author: Matthias Bisping <matthias.bisping@axbit.com>
Date: Wed Feb 1 17:07:33 2023 +0100
Refactoring: Move
Move font related functions into font module
commit de9b3bad93d91b2d1820b59403fc357e243238e6
Author: Matthias Bisping <matthias.bisping@axbit.com>
Date: Wed Feb 1 17:05:47 2023 +0100
Refactoring: Move
Move font picker into new font module
commit 9480d58a8a77b3feb7206cb1b7ac5c8a25516b39
Author: Matthias Bisping <matthias.bisping@axbit.com>
Date: Wed Feb 1 16:59:31 2023 +0100
Refactoring: Move
Move line formatters into their own module
commit cc0094d3f73b258a0b89353981529e7fa6978b53
Author: Matthias Bisping <matthias.bisping@axbit.com>
Date: Wed Feb 1 16:54:08 2023 +0100
Refactoring: Move
Move random content rectangle into its own module
commit 93a52080df8f5aa39b3b29f2c9a8dcbc8d72ad9d
Author: Matthias Bisping <matthias.bisping@axbit.com>
Date: Wed Feb 1 16:52:57 2023 +0100
Remove unused code
commit 4ec3429dec932cadd828376610950b8ad84a51f4
Author: Matthias Bisping <matthias.bisping@axbit.com>
Date: Wed Feb 1 16:51:03 2023 +0100
Refactoring: Move
Move page partitioner into its own module
commit bdcb2f1bef36357ea048c4f00b9dccfa25b13bd9
Author: Matthias Bisping <matthias.bisping@axbit.com>
Date: Wed Feb 1 16:42:55 2023 +0100
Refactoring: Move
commit 845d1691949dcba049737af29fcee735825ecb8f
Author: Matthias Bisping <matthias.bisping@axbit.com>
Date: Wed Feb 1 16:39:39 2023 +0100
Refactoring
commit 56c10490b965ccf3ca81aa9ba0403d9068871688
Author: Matthias Bisping <matthias.bisping@axbit.com>
Date: Wed Feb 1 16:36:21 2023 +0100
Refactoring
commit 740a9cb3c25710a46452fa28dbef011daa03d6ed
Author: Matthias Bisping <matthias.bisping@axbit.com>
Date: Wed Feb 1 16:33:32 2023 +0100
Refactoring
commit b3cf3e44548c71e7eff90e94ce8ce671a0d8f343
Author: Matthias Bisping <matthias.bisping@axbit.com>
Date: Wed Feb 1 16:29:03 2023 +0100
Refactoring
Add fixture for page partitioner
commit 2fb450943e74d0a2a49ca0e20c9507d0230e4373
Author: Matthias Bisping <matthias.bisping@axbit.com>
Date: Wed Feb 1 16:25:50 2023 +0100
Refactoring: Move
commit fd76933b5ac1fbab1b508ef1f3f199d04189cf81
Author: Matthias Bisping <matthias.bisping@axbit.com>
Date: Wed Feb 1 16:16:16 2023 +0100
Refactoring: Move
Move image operations such as blurring into their own module.
commit 809590054315266286c75fb0ef2f81b506aaf20c
Author: Matthias Bisping <matthias.bisping@axbit.com>
Date: Wed Feb 1 16:10:48 2023 +0100
Fix effectless bug
commit d42f053c81105e3144fcc54a7c6e924c777b3665
Author: Matthias Bisping <matthias.bisping@axbit.com>
Date: Wed Feb 1 13:22:16 2023 +0100
Refactoring: Re-order
commit 04a617b9df0ee62e73f87508c8b09c4d3817a6e3
Author: Matthias Bisping <matthias.bisping@axbit.com>
Date: Wed Feb 1 13:19:25 2023 +0100
Refactoring
Move content rectangle base class
193 lines
6.0 KiB
Python
193 lines
6.0 KiB
Python
import io
|
|
import random
|
|
from functools import lru_cache, partial
|
|
|
|
import loguru
|
|
import numpy as np
|
|
from PIL import Image
|
|
from matplotlib import pyplot as plt
|
|
from matplotlib.colors import ListedColormap
|
|
|
|
from cv_analysis.utils.geometric import is_square_like, is_wide, is_tall
|
|
from cv_analysis.utils.image_operations import superimpose
|
|
from cv_analysis.utils.rectangle import Rectangle
|
|
from synthesis.random import rnd, probably, maybe
|
|
from synthesis.segment.random_content_rectangle import RandomContentRectangle
|
|
from synthesis.text.text import generate_random_words
|
|
|
|
|
|
class RandomPlot(RandomContentRectangle):
|
|
def __init__(self, x1, y1, x2, y2, seed=None):
|
|
super().__init__(x1, y1, x2, y2, seed=seed)
|
|
|
|
self.cmap = pick_colormap()
|
|
|
|
def __call__(self, *args, **kwargs):
|
|
pass
|
|
|
|
def generate_random_plot(self, rectangle: Rectangle):
|
|
|
|
if is_square_like(rectangle):
|
|
plt_fn = rnd.choice(
|
|
[
|
|
self.generate_random_line_plot,
|
|
self.generate_random_bar_plot,
|
|
self.generate_random_scatter_plot,
|
|
self.generate_random_histogram,
|
|
self.generate_random_pie_chart,
|
|
]
|
|
)
|
|
elif is_wide(rectangle):
|
|
plt_fn = rnd.choice(
|
|
[
|
|
self.generate_random_line_plot,
|
|
self.generate_random_histogram,
|
|
self.generate_random_bar_plot,
|
|
]
|
|
)
|
|
elif is_tall(rectangle):
|
|
plt_fn = rnd.choice(
|
|
[
|
|
self.generate_random_bar_plot,
|
|
self.generate_random_histogram,
|
|
]
|
|
)
|
|
else:
|
|
plt_fn = self.generate_random_scatter_plot
|
|
|
|
plt_fn(rectangle)
|
|
|
|
def generate_random_bar_plot(self, rectangle: Rectangle):
|
|
x = sorted(np.random.randint(low=1, high=11, size=5))
|
|
y = np.random.randint(low=1, high=11, size=5)
|
|
bar_fn = partial(
|
|
plt.bar,
|
|
log=random.choice([True, False]),
|
|
)
|
|
self.__generate_random_plot(bar_fn, rectangle, x, y)
|
|
|
|
def generate_random_line_plot(self, rectangle: Rectangle):
|
|
f = rnd.choice([np.sin, np.cos, np.tan, np.exp, np.log, np.sqrt, np.square])
|
|
|
|
x = np.linspace(0, 10, 100)
|
|
y = f(x)
|
|
|
|
plot_fn = partial(
|
|
plt.plot,
|
|
)
|
|
|
|
self.__generate_random_plot(plot_fn, rectangle, x, y)
|
|
|
|
def generate_random_scatter_plot(self, rectangle: Rectangle):
|
|
n = rnd.randint(10, 40)
|
|
x = np.random.normal(size=n)
|
|
y = np.random.normal(size=n)
|
|
scatter_fn = partial(
|
|
plt.scatter,
|
|
cmap=self.cmap,
|
|
marker=rnd.choice(["o", "*", "+", "x"]),
|
|
)
|
|
|
|
self.__generate_random_plot(scatter_fn, rectangle, x, y)
|
|
|
|
def generate_random_histogram(self, rectangle: Rectangle):
|
|
x = np.random.normal(size=100)
|
|
hist_fn = partial(
|
|
plt.hist,
|
|
orientation=random.choice(["horizontal", "vertical"]),
|
|
histtype=random.choice(["bar", "barstacked", "step", "stepfilled"]),
|
|
log=random.choice([True, False]),
|
|
stacked=random.choice([True, False]),
|
|
density=random.choice([True, False]),
|
|
cumulative=random.choice([True, False]),
|
|
)
|
|
self.__generate_random_plot(hist_fn, rectangle, x, random.randint(5, 20))
|
|
|
|
def generate_random_pie_chart(self, rectangle: Rectangle):
|
|
|
|
n = random.randint(3, 7)
|
|
x = np.random.uniform(size=n)
|
|
pie_fn = partial(
|
|
plt.pie,
|
|
shadow=True,
|
|
startangle=90,
|
|
pctdistance=0.85,
|
|
labeldistance=1.1,
|
|
colors=self.cmap(np.linspace(0, 1, 10)),
|
|
)
|
|
self.__generate_random_plot(
|
|
pie_fn,
|
|
rectangle,
|
|
x,
|
|
np.random.uniform(0, 0.1, size=n),
|
|
plot_kwargs=self.generate_plot_kwargs(keywords=["a"]),
|
|
)
|
|
|
|
def generate_plot_kwargs(self, keywords=None):
|
|
|
|
kwargs = {
|
|
"color": rnd.choice(self.cmap.colors),
|
|
"linestyle": rnd.choice(["-", "--", "-.", ":"]),
|
|
"linewidth": rnd.uniform(1, 4),
|
|
}
|
|
|
|
return kwargs if not keywords else {k: v for k, v in kwargs.items() if k in keywords}
|
|
|
|
def __generate_random_plot(self, plot_fn, rectangle: Rectangle, x, y, plot_kwargs=None):
|
|
|
|
plot_kwargs = self.generate_plot_kwargs() if plot_kwargs is None else plot_kwargs
|
|
|
|
fig, ax = plt.subplots()
|
|
fig.set_size_inches(rectangle.width / 100, rectangle.height / 100)
|
|
fig.tight_layout(pad=0)
|
|
|
|
plot_fn(x, y, **plot_kwargs)
|
|
ax.set_facecolor("none")
|
|
|
|
probably() and ax.set_title(generate_random_words(1, 3))
|
|
|
|
# disable axes at random
|
|
maybe() and ax.set_xticks([])
|
|
maybe() and ax.set_yticks([])
|
|
maybe() and ax.set_xticklabels([])
|
|
maybe() and ax.set_yticklabels([])
|
|
maybe() and ax.set_xlabel("")
|
|
maybe() and ax.set_ylabel("")
|
|
maybe() and ax.set_title("")
|
|
maybe() and ax.set_frame_on(False)
|
|
|
|
# remove spines at random
|
|
maybe() and (ax.spines["top"].set_visible(False) or ax.spines["right"].set_visible(False))
|
|
|
|
image = dump_plt_to_image(rectangle)
|
|
assert image.mode == "RGBA"
|
|
|
|
self.content = image if not self.content else superimpose(self.content, image)
|
|
|
|
|
|
@lru_cache(maxsize=None)
|
|
def pick_colormap() -> ListedColormap:
|
|
cmap_name = rnd.choice(
|
|
[
|
|
"viridis",
|
|
"plasma",
|
|
"inferno",
|
|
"magma",
|
|
"cividis",
|
|
],
|
|
)
|
|
loguru.logger.info(f"Using colormap {cmap_name}")
|
|
cmap = plt.get_cmap(cmap_name)
|
|
return cmap
|
|
|
|
|
|
def dump_plt_to_image(rectangle):
|
|
buf = io.BytesIO()
|
|
plt.savefig(buf, format="png", transparent=True)
|
|
buf.seek(0)
|
|
image = Image.open(buf)
|
|
image = image.resize((rectangle.width, rectangle.height))
|
|
buf.close()
|
|
plt.close()
|
|
return image
|