Skip to content

Commit 65bd9ff

Browse files
committed
Improve .plt for difstibutions with large std
1 parent 37a8595 commit 65bd9ff

File tree

5 files changed

+3298
-1066
lines changed

5 files changed

+3298
-1066
lines changed

README.md

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,10 @@
1-
💟 Lovely NumPy
2-
================
1+
# 💟 Lovely NumPy
32

4-
<!-- WARNING: THIS FILE WAS AUTOGENERATED! DO NOT EDIT! -->
53

6-
<div>
4+
<!-- WARNING: THIS FILE WAS AUTOGENERATED! DO NOT EDIT! -->
75

86
## [Read full docs](https://xl0.github.io/lovely-numpy)
97

10-
</div>
11-
128
### More lovely stuff
139

1410
##### Working with numbers

lovely_numpy/repr_plt.py

Lines changed: 17 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,6 @@ def normal_pdf( x :np.ndarray,
2727
= \dfrac{e^{- \frac{1}{2}\left(\frac{x-\mu}{\sigma}\right)^{2}}}
2828
{\sigma \sqrt{2\pi}}$$"""
2929

30-
np.e
31-
# dev = x.device
32-
3330
mean = np.array(mean) #if not isinstance(mean, torch.Tensor) else mean
3431
std = np.array(std) #.to(dev) if not isinstance(std, torch.Tensor) else std
3532

@@ -46,22 +43,22 @@ def sample( x :np.ndarray,
4643
# - samples from x
4744
# - original x min (None = no good numbes in x)
4845
# - original x max (None = no good numbes in x)
49-
46+
5047
# Ignore NaN and Inf.
5148
x = x[ np.isfinite(x) ]
5249
x_min = x_max = None
5350

54-
if x.size:
51+
if x.size:
5552
x_min, x_max = x.min(), x.max()
56-
53+
5754
# An option to ignore zeros
5855
if not plt0: x = x[x != 0.]
5956

6057
if x.size > max_s and max_s > 0:
6158
rng = np.random.default_rng( get_config().plt_seed )
6259
x = rng.choice(x.reshape(-1), max_s) # Sample with replacement for efficiency
6360

64-
return (x, x_min, x_max)
61+
return (x, x_min, x_max)
6562

6663
# %% ../nbs/02_repr_plt.ipynb 7
6764
def find_xlims( x_min :Union[float, None],
@@ -71,7 +68,7 @@ def find_xlims( x_min :Union[float, None],
7168
center :str):
7269

7370
assert center in ["zero", "mean", "range"]
74-
71+
7572
if x_min is None or x_max is None: return (-1., 1,)
7673
if x_min == x_max and center == "range": center = "zero"
7774
if x_mean is None or x_std is None and center == "mean": center = "zero"
@@ -92,9 +89,9 @@ def find_xlims( x_min :Union[float, None],
9289
# Center the plot around zero
9390
abs_max_value = max(abs(x_min), abs(x_max), 1.)
9491
xlim_min, xlim_max = -abs_max_value, abs_max_value
95-
9692

97-
# Give some extra space around the
93+
94+
# Give some extra space around the data
9895
xlim_min -= abs(xlim_max - xlim_min) * 0.02
9996
xlim_max += abs(xlim_max - xlim_min) * 0.02
10097

@@ -111,7 +108,7 @@ def plot_histogram( x :np.ndarray,
111108
# Adjust the number of bins proportional to the fraction of x axis occupied
112109
# by the histogram
113110
xlims = ax.get_xlim()
114-
111+
115112
bins = min(bins, 100)
116113
bins = np.ceil( bins * ( (x.max()-x.min())/(xlims[1]-xlims[0]) ) ).astype(int)
117114
bins = max(bins, 10)
@@ -148,7 +145,7 @@ def plot_sigmas(x_min :Union[float, None],
148145

149146
for s in range(-sigmas, sigmas+1):
150147
x_pos = (x_mean + s*x_std)
151-
if xlims[0] < x_pos < xlims[1]:
148+
if xlims[0] < x_pos < xlims[1] and (sigmas <= 20 or not s%10):
152149
greek = ["-σ", "μ", "+σ"][s+1] if -1 <= s <= 1 else f"{s:+}σ"
153150
weight='bold' if not s else None
154151
ax.axvline(x_pos, 0, 1, c="black")
@@ -196,7 +193,7 @@ def plot_str(t_str, ax):
196193

197194
# %% ../nbs/02_repr_plt.ipynb 13
198195
@config(show_mem_above=np.inf)
199-
def fig_plot( x :np.ndarray, #
196+
def fig_plot( x :np.ndarray, #
200197
center :str ="zero", # Center plot on `zero`, `mean`, or `range`
201198
max_s :int =10000, # Draw up to this many samples. =0 to draw all
202199
plt0 :Any =True, # Take zero values into account
@@ -210,14 +207,14 @@ def fig_plot( x :np.ndarray, #
210207
# display backend-specific info.
211208
if summary is None: summary = str(lovely(x, color=False))
212209
orig_numel = x.size
213-
210+
214211
x, x_min, x_max = sample(x, max_s, plt0)
215212
x_mean, x_std = (x.mean(), x.std(ddof=ddof)) if x.size else (None,None)
216213

217214

218215
t_str = ""
219216
if x.size != orig_numel:
220-
t_str += str(x.size)
217+
t_str += str(x.size)
221218
if not plt0: t_str += " non-zero"
222219
t_str += f" samples (μ={pretty_str(x_mean)}, σ={pretty_str(x_std)}) of "
223220
t_str += summary
@@ -235,15 +232,15 @@ def fig_plot( x :np.ndarray, #
235232
ax.set_xlim(*xlims)
236233
plot_histogram(x, ax)
237234
plot_pdf(x_mean, x_std, ax)
238-
235+
239236
# Add extra space to make sure the labels clear the histogram
240237
ylim = ax.get_ylim()
241238
ax.set_ylim( ylim[0], ylim[1]*1.3 )
242239

243240
plot_sigmas(x_min, x_max, x_mean, x_std, ax)
244241
plot_minmax(x_min, x_max, ax)
245242
plot_str(t_str, ax)
246-
243+
247244
ax.set_yticks([])
248245

249246
if show: plt.show()
@@ -253,9 +250,9 @@ def fig_plot( x :np.ndarray, #
253250

254251
# %% ../nbs/02_repr_plt.ipynb 14
255252
# This is here for the monkey-patched tensor use case.
256-
# Gives the ability to call both .plt and .plt(ax=ax).
253+
# Gives the ability to call both .plt and .plt(ax=ax).
257254

258-
class PlotProxy():
255+
class PlotProxy():
259256
"""Flexible `PIL.Image.Image` wrapper"""
260257

261258
def __init__(self, x:np.ndarray):
@@ -276,7 +273,7 @@ def __call__( self,
276273
self.params.update( { k:v for
277274
k,v in locals().items()
278275
if k != "self" and v is not None } )
279-
276+
280277
_ = self.fig # Trigger figure generation
281278
return self
282279

lovely_numpy/repr_rgb.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,12 +62,12 @@ def fig_rgb(x :np.ndarray, # Array to display. [[...], C,H,W] o
6262

6363
if ax is None:
6464
fig = plt.figure(frameon=False, figsize=(x.shape[1] * 0.01, x.shape[0]*0.01) )
65-
if close: plt.close(fig)
6665
fig.set_dpi(100)
6766

6867
ax = fig.add_axes([0,0,1,1])
6968
ax.set_axis_off()
7069
ax.set_xlim(0, x.shape[1]+1)
70+
if close: plt.close(fig)
7171

7272
ax.imshow(x, interpolation="none")
7373
if show: plt.show()

nbs/01_repr_rgb.ipynb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,12 +101,12 @@
101101
"\n",
102102
" if ax is None:\n",
103103
" fig = plt.figure(frameon=False, figsize=(x.shape[1] * 0.01, x.shape[0]*0.01) )\n",
104-
" if close: plt.close(fig)\n",
105104
" fig.set_dpi(100)\n",
106105
"\n",
107106
" ax = fig.add_axes([0,0,1,1])\n",
108107
" ax.set_axis_off()\n",
109108
" ax.set_xlim(0, x.shape[1]+1)\n",
109+
" if close: plt.close(fig)\n",
110110
"\n",
111111
" ax.imshow(x, interpolation=\"none\")\n",
112112
" if show: plt.show()\n",
@@ -121,7 +121,7 @@
121121
"outputs": [
122122
{
123123
"data": {
124-
"image/png": "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",
124+
"image/png": "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",
125125
"text/plain": [
126126
"<Figure size 600x200 with 3 Axes>"
127127
]

0 commit comments

Comments
 (0)