Skip to content

Commit 2716f1f

Browse files
Merge pull request #1 from davidnabergoj/dev
Dev
2 parents e495988 + ab0f364 commit 2716f1f

22 files changed

+720
-138
lines changed

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ Supported image output formats include popular formats such as JPG, PNG, BMP. Su
2525
pip install bootplot
2626
```
2727

28-
Alternatively, you can install **bootplot** without PyPI:
28+
Alternatively, you can install **bootplot** using:
2929

3030
```
3131
git clone https://github.com/davidnabergoj/bootplot
@@ -59,6 +59,8 @@ def plot_regression(data_subset, data_full, ax):
5959
bbox_kwargs = dict(facecolor='none', edgecolor='black', pad=10.0)
6060
ax.text(x=0, y=-8, s=f'RMSE: {rmse:.4f}', fontsize=12, ha='center', bbox=bbox_kwargs)
6161

62+
ax.set_xlim(-10, 10)
63+
ax.set_ylim(-10, 10)
6264

6365
if __name__ == '__main__':
6466
np.random.seed(0)
@@ -74,8 +76,6 @@ if __name__ == '__main__':
7476
dataset,
7577
output_image_path='demo_image.png',
7678
output_animation_path='demo_animation.gif',
77-
xlim=(-10, 10),
78-
ylim=(-10, 10),
7979
verbose=True
8080
)
8181
```

bootplot/backend/__init__.py

Whitespace-only changes.

bootplot/backend/base.py

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
from abc import abstractmethod, ABC
2+
from typing import Tuple, Union
3+
4+
import numpy as np
5+
import matplotlib.pyplot as plt
6+
import pandas as pd
7+
from tqdm import tqdm
8+
9+
import bootplot.backend.matplotlib
10+
11+
12+
class Backend(ABC):
13+
def __init__(self,
14+
f: callable,
15+
data: Union[np.ndarray, pd.DataFrame],
16+
m: int,
17+
output_size_px: Tuple[int, int]):
18+
self.output_size_px = output_size_px
19+
self.f = f
20+
self.data = data
21+
self.m = m
22+
23+
@abstractmethod
24+
def create_figure(self):
25+
raise NotImplemented
26+
27+
def plot(self):
28+
indices = np.random.randint(low=0, high=len(self.data), size=len(self.data))
29+
if isinstance(self.data, pd.DataFrame):
30+
return self.f(self.data.iloc[indices], self.data, *self.plot_args)
31+
elif isinstance(self.data, np.ndarray):
32+
return self.f(self.data[indices], self.data, *self.plot_args)
33+
34+
@abstractmethod
35+
def plot_to_array(self) -> np.ndarray:
36+
raise NotImplemented
37+
38+
@abstractmethod
39+
def clear_figure(self):
40+
raise NotImplemented
41+
42+
@abstractmethod
43+
def close_figure(self):
44+
raise NotImplemented
45+
46+
@property
47+
@abstractmethod
48+
def plot_args(self):
49+
raise NotImplemented
50+
51+
52+
class Basic(Backend):
53+
def __init__(self, f: callable, data: Union[np.ndarray, pd.DataFrame], m: int, output_size_px: Tuple[int, int]):
54+
super().__init__(f, data, m, output_size_px)
55+
self.cached_image = None
56+
57+
def plot(self):
58+
self.cached_image = super().plot()
59+
60+
def create_figure(self):
61+
pass
62+
63+
def plot_to_array(self) -> np.ndarray:
64+
return self.cached_image
65+
66+
def clear_figure(self):
67+
pass
68+
69+
def close_figure(self):
70+
pass
71+
72+
@property
73+
def plot_args(self):
74+
return []
75+
76+
77+
class Matplotlib(Backend):
78+
def __init__(self,
79+
f: callable,
80+
data: Union[np.ndarray, pd.DataFrame],
81+
m: int,
82+
output_size_px: Tuple[int, int] = (512, 512)):
83+
self.fig = None
84+
self.ax = None
85+
super().__init__(f, data, m, output_size_px)
86+
87+
def create_figure(self):
88+
self.fig, self.ax = bootplot.backend.matplotlib.create_figure(self.output_size_px)
89+
90+
def plot_to_array(self) -> np.ndarray:
91+
return bootplot.backend.matplotlib.plot_to_array(self.fig)
92+
93+
def clear_figure(self):
94+
bootplot.backend.matplotlib.clear_figure(self.ax)
95+
96+
def close_figure(self):
97+
bootplot.backend.matplotlib.close_figure(None)
98+
99+
@property
100+
def plot_args(self):
101+
return [self.ax]
102+
103+
104+
class GGPlot2(Backend):
105+
def __init__(self,
106+
f: callable,
107+
data: Union[np.ndarray, pd.DataFrame],
108+
m: int,
109+
output_size_px: Tuple[int, int] = (512, 512)):
110+
super().__init__(f, data, m, output_size_px)
111+
112+
def create_figure(self):
113+
raise NotImplemented
114+
115+
def plot_to_array(self) -> np.ndarray:
116+
raise NotImplemented
117+
118+
def clear_figure(self):
119+
raise NotImplemented
120+
121+
def close_figure(self):
122+
raise NotImplemented
123+
124+
@property
125+
def plot_args(self):
126+
raise NotImplemented
127+
128+
129+
class Plotly(Backend):
130+
def __init__(self,
131+
f: callable,
132+
data: Union[np.ndarray, pd.DataFrame],
133+
m: int,
134+
output_size_px: Tuple[int, int] = (512, 512)):
135+
super().__init__(f, data, m, output_size_px)
136+
137+
def create_figure(self):
138+
raise NotImplemented
139+
140+
def plot_to_array(self) -> np.ndarray:
141+
raise NotImplemented
142+
143+
def clear_figure(self):
144+
raise NotImplemented
145+
146+
def close_figure(self):
147+
raise NotImplemented
148+
149+
@property
150+
def plot_args(self):
151+
raise NotImplemented
152+
153+
154+
def create_backend(backend_string, f, data, m, **kwargs):
155+
if backend_string == 'matplotlib':
156+
return Matplotlib(f=f, data=data, m=m, **kwargs)
157+
elif backend_string == 'basic':
158+
return Basic(f=f, data=data, m=m, **kwargs)
159+
else:
160+
raise NotImplemented

bootplot/backend/matplotlib.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import io
2+
from typing import Tuple
3+
4+
import numpy as np
5+
import matplotlib.pyplot as plt
6+
7+
8+
def plot_to_array(fig):
9+
with io.BytesIO() as buff:
10+
fig.savefig(buff, format='raw')
11+
buff.seek(0)
12+
data = np.frombuffer(buff.getvalue(), dtype=np.uint8)
13+
w, h = fig.canvas.get_width_height()
14+
im = data.reshape((int(h), int(w), -1))
15+
return im
16+
17+
18+
def create_figure(output_size_px: Tuple[int, int]):
19+
px_size_inches = 1 / plt.rcParams['figure.dpi']
20+
fig, ax = plt.subplots(
21+
figsize=(output_size_px[0] * px_size_inches, output_size_px[1] * px_size_inches)
22+
)
23+
return fig, ax
24+
25+
26+
def clear_figure(ax):
27+
ax.cla()
28+
29+
30+
def close_figure(fig):
31+
plt.close(fig)

0 commit comments

Comments
 (0)