cetin
11 months ago
6 changed files with 625 additions and 44 deletions
-
5.vscode/settings.json
-
65B_tasks.ipynb
-
250B_updown.ipynb
-
9Projektpraktikum.code-workspace
-
BINmethods/__pycache__/adashof.cpython-310.pyc
-
340methods/adashof.py
@ -1,3 +1,6 @@ |
|||||
{ |
{ |
||||
"python.envFile": "/auto/work/cetin/LHCb/reco_tuner/env/tuner_env/envs/", |
|
||||
|
// "python.envFile": "/auto/work/cetin/LHCb/reco_tuner/env/tuner_env/envs/", |
||||
|
"python.analysis.completeFunctionParens": true, |
||||
|
"python.analysis.enablePytestExtra": false, |
||||
|
"python.analysis.extraCommitChars": true, |
||||
} |
} |
65
B_tasks.ipynb
File diff suppressed because one or more lines are too long
View File
File diff suppressed because one or more lines are too long
View File
250
B_updown.ipynb
File diff suppressed because one or more lines are too long
View File
File diff suppressed because one or more lines are too long
View File
@ -1,10 +1,13 @@ |
|||||
{ |
{ |
||||
"folders": [ |
"folders": [ |
||||
{ |
{ |
||||
"path": "./", |
|
||||
} |
|
||||
|
"path": "./" |
||||
|
}, |
||||
], |
], |
||||
"settings": { |
"settings": { |
||||
"python.analysis.completeFunctionParens": true |
|
||||
|
"python.analysis.completeFunctionParens": true, |
||||
|
"python.analysis.enablePytestExtra": false, |
||||
|
|
||||
|
"python.languageServer": "Pylance", |
||||
} |
} |
||||
} |
} |
Binary file not shown.
@ -0,0 +1,340 @@ |
|||||
|
|
||||
|
# coding: utf-8 |
||||
|
# flake8: noqa |
||||
|
|
||||
|
# # `adashof`: Functions used in the notebooks of the blog |
||||
|
# |
||||
|
# [Blog](http://werthmuller.org/blog) |
||||
|
# [Repo](http://github.com/prisae/blog-notebooks) |
||||
|
# |
||||
|
# - circle : Create circle on figure with axes of different sizes. |
||||
|
# - move_sn_y : Move scientific notation exponent from top to the side. |
||||
|
# - fillgrid : Fill rectangular grid with colours or a colour and transparency. |
||||
|
# - checksize : Check size of pdf figure, and adjust if required. |
||||
|
# - cm2in : Convert centimetres to inches |
||||
|
|
||||
|
# In[1]: |
||||
|
|
||||
|
import numpy as np |
||||
|
import matplotlib as mpl |
||||
|
from matplotlib import cm |
||||
|
import matplotlib.pyplot as plt |
||||
|
|
||||
|
|
||||
|
# In[2]: |
||||
|
|
||||
|
def circle(xy, radius, kwargs=None): |
||||
|
"""Create circle on figure with axes of different sizes. |
||||
|
|
||||
|
Plots a circle on the current axes using `plt.Circle`, taking into account |
||||
|
the figure size and the axes units. |
||||
|
|
||||
|
It is done by plotting in the figure coordinate system, taking the aspect |
||||
|
ratio into account. In this way, the data dimensions do not matter. |
||||
|
However, if you adjust `xlim` or `ylim` after plotting `circle`, it will |
||||
|
screw them up; set `plt.axis` before calling `circle`. |
||||
|
|
||||
|
Parameters |
||||
|
---------- |
||||
|
xy, radius, kwars : |
||||
|
As required for `plt.Circle`. |
||||
|
""" |
||||
|
|
||||
|
# Get current figure and axis |
||||
|
fig = mpl.pyplot.gcf() |
||||
|
ax = fig.gca() |
||||
|
|
||||
|
# Calculate figure dimension ratio width/height |
||||
|
pr = fig.get_figwidth()/fig.get_figheight() |
||||
|
|
||||
|
# Get the transScale (important if one of the axis is in log-scale) |
||||
|
tscale = ax.transScale + (ax.transLimits + ax.transAxes) |
||||
|
ctscale = tscale.transform_point(xy) |
||||
|
cfig = fig.transFigure.inverted().transform(ctscale) |
||||
|
|
||||
|
# Create circle |
||||
|
if kwargs == None: |
||||
|
circ = mpl.patches.Ellipse(cfig, radius, radius*pr, |
||||
|
transform=fig.transFigure) |
||||
|
else: |
||||
|
circ = mpl.patches.Ellipse(cfig, radius, radius*pr, |
||||
|
transform=fig.transFigure, **kwargs) |
||||
|
|
||||
|
# Draw circle |
||||
|
ax.add_artist(circ) |
||||
|
|
||||
|
|
||||
|
# In[3]: |
||||
|
|
||||
|
def move_sn_y(offs=0, dig=0, side='left', omit_last=False): |
||||
|
"""Move scientific notation exponent from top to the side. |
||||
|
|
||||
|
Additionally, one can set the number of digits after the comma |
||||
|
for the y-ticks, hence if it should state 1, 1.0, 1.00 and so forth. |
||||
|
|
||||
|
Parameters |
||||
|
---------- |
||||
|
offs : float, optional; <0> |
||||
|
Horizontal movement additional to default. |
||||
|
dig : int, optional; <0> |
||||
|
Number of decimals after the comma. |
||||
|
side : string, optional; {<'left'>, 'right'} |
||||
|
To choose the side of the y-axis notation. |
||||
|
omit_last : bool, optional; <False> |
||||
|
If True, the top y-axis-label is omitted. |
||||
|
|
||||
|
Returns |
||||
|
------- |
||||
|
locs : list |
||||
|
List of y-tick locations. |
||||
|
|
||||
|
Note |
||||
|
---- |
||||
|
This is kind of a non-satisfying hack, which should be handled more |
||||
|
properly. But it works. Functions to look at for a better implementation: |
||||
|
ax.ticklabel_format |
||||
|
ax.yaxis.major.formatter.set_offset_string |
||||
|
""" |
||||
|
|
||||
|
# Get the ticks |
||||
|
locs, _ = mpl.pyplot.yticks() |
||||
|
|
||||
|
# Put the last entry into a string, ensuring it is in scientific notation |
||||
|
# E.g: 123456789 => '1.235e+08' |
||||
|
llocs = '%.3e' % locs[-1] |
||||
|
|
||||
|
# Get the magnitude, hence the number after the 'e' |
||||
|
# E.g: '1.235e+08' => 8 |
||||
|
yoff = int(str(llocs).split('e')[1]) |
||||
|
|
||||
|
# If omit_last, remove last entry |
||||
|
if omit_last: |
||||
|
slocs = locs[:-1] |
||||
|
else: |
||||
|
slocs = locs |
||||
|
|
||||
|
# Set ticks to the requested precision |
||||
|
form = r'$%.'+str(dig)+'f$' |
||||
|
mpl.pyplot.yticks(locs, list(map(lambda x: form % x, slocs/(10**yoff)))) |
||||
|
|
||||
|
# Define offset depending on the side |
||||
|
if side == 'left': |
||||
|
offs = -.18 - offs # Default left: -0.18 |
||||
|
elif side == 'right': |
||||
|
offs = 1 + offs # Default right: 1.0 |
||||
|
|
||||
|
# Plot the exponent |
||||
|
mpl.pyplot.text(offs, .98, r'$\times10^{%i}$' % yoff, transform = |
||||
|
mpl.pyplot.gca().transAxes, verticalalignment='top') |
||||
|
|
||||
|
# Return the locs |
||||
|
return locs |
||||
|
|
||||
|
|
||||
|
# In[4]: |
||||
|
|
||||
|
def fillgrid(xval, yval, values, style='colour', cmap=cm.Spectral, |
||||
|
unicol='#000000', lc='k', lw=0.5): |
||||
|
"""Fill rectangular grid with colours or a colour and transparency. |
||||
|
|
||||
|
Parameters |
||||
|
---------- |
||||
|
xval, yval : array |
||||
|
Grid-points in x- and in y-direction. |
||||
|
values : array, dimension: (x-1)-by-(y-1) |
||||
|
Values between 0 and 1 |
||||
|
style : string, optional; {<'colour'>, 'alpha'} |
||||
|
Defines if values represent colour or alpha. |
||||
|
cmap : mpl.cm-element, optional |
||||
|
`Colormap` colours are chosen from; only used if style='colour' |
||||
|
unicol : HEX-colour |
||||
|
Colour used with transparency; only used if style='alpha' |
||||
|
lc, lw : optional |
||||
|
Line colour and width, as in standard plots. |
||||
|
|
||||
|
Returns |
||||
|
------- |
||||
|
rct : list |
||||
|
List of plotted polygon patches. |
||||
|
""" |
||||
|
|
||||
|
# Ravel values, and set NaN's to zero |
||||
|
rval = values.ravel() |
||||
|
rvalnan = np.isnan(rval) |
||||
|
rval[rvalnan] = 0 |
||||
|
|
||||
|
# Define colour depending on style |
||||
|
if style == 'alpha': |
||||
|
# Create RGB from HEX |
||||
|
unicol = mpl.colors.colorConverter.to_rgb(unicol) |
||||
|
# Repeat colour for all values, |
||||
|
# filling the value into the transparency column |
||||
|
colour = np.vstack((np.repeat(unicol, len(rval)).reshape(3, -1), |
||||
|
rval)).transpose() |
||||
|
else: |
||||
|
# Split cmap into 101 points from 0 to 1 |
||||
|
cmcol = cmap(np.linspace(0, 1, 101)) |
||||
|
# Map the values onto these |
||||
|
colour = cmcol[list(map(int, 100*rval))] |
||||
|
# Set transparency to 0 for NaN's |
||||
|
colour[rvalnan, -1] = 0 |
||||
|
|
||||
|
# Draw all rectangles at once |
||||
|
xxval = np.array([xval[:-1], xval[:-1], xval[1:], xval[1:]]).repeat( |
||||
|
len(yval)-1, axis=1).reshape(4, -1) |
||||
|
yyval = np.array([yval[:-1], yval[1:], yval[1:], yval[:-1]]).repeat( |
||||
|
len(xval)-1, axis=0).reshape(4, -1) |
||||
|
rct = mpl.pyplot.gca().fill(xxval, yyval, lw=lw, ec=lc) |
||||
|
|
||||
|
# Map the colour onto a list |
||||
|
cls = list(map(mpl.colors.rgb2hex, colour)) |
||||
|
|
||||
|
# Adjust colour and transparency for all cells |
||||
|
for ind in range(len(rct)): |
||||
|
rct[ind].set_facecolor(cls[ind]) |
||||
|
rct[ind].set_alpha(colour[ind, -1]) |
||||
|
|
||||
|
return rct |
||||
|
|
||||
|
|
||||
|
# In[5]: |
||||
|
|
||||
|
def checksize(fhndl, name, dsize, precision=0.01, extent=0.05, kwargs={}, _cf=False): |
||||
|
"""Print figure with 'name.pdf', check size, compare with dsize, and adjust if required |
||||
|
|
||||
|
Parameters |
||||
|
---------- |
||||
|
fhndl : figure-handle |
||||
|
Figure handle of the figure to be saved. |
||||
|
name : string |
||||
|
Figure name. |
||||
|
dsize : list of two floats |
||||
|
Desired size of pdf in cm. |
||||
|
precision : float, optional; <0.01> |
||||
|
Desired precision in cm of the dimension, defaults to 1 mm. |
||||
|
extent : float or list of floats, optional; <0.01> |
||||
|
- If float, then bbox_inches is set to tight, and pad_inches=extent. |
||||
|
- If it is an array of two numbers it sets the percentaged extent-width, |
||||
|
`Bbox.expanded`. |
||||
|
- If it is an array of four numbers it sets [x0, y0, x1, y1] of Bbox. |
||||
|
kwargs : dict |
||||
|
Other input arguments that will be passed on to `plt.savefig`; e.g. dpi or facecolor. |
||||
|
_cf : Internal parameter for recursion and adjustment. |
||||
|
""" |
||||
|
|
||||
|
# Import PyPDF2 |
||||
|
from PyPDF2 import PdfFileReader |
||||
|
|
||||
|
# Check `extent` input and set bbox_inches and pad_inches accordingly |
||||
|
if np.size(extent) == 1: |
||||
|
bbox_inches = 'tight' |
||||
|
pad_inches = extent |
||||
|
else: |
||||
|
fext = fhndl.gca().get_window_extent().transformed( |
||||
|
fhndl.dpi_scale_trans.inverted()) |
||||
|
if np.size(extent) == 2: |
||||
|
bbox_inches = fext.expanded(extent[0], extent[1]) |
||||
|
elif np.size(extent) == 4: |
||||
|
fext.x0, fext.y0, fext.x1, fext.y1 = extent |
||||
|
extent = [1, 1] # set extent to [1, 1] for recursion |
||||
|
bbox_inches = fext |
||||
|
pad_inches=0 |
||||
|
|
||||
|
# Save the figure |
||||
|
fhndl.savefig(name+'.pdf', bbox_inches=bbox_inches, pad_inches=pad_inches, **kwargs) |
||||
|
|
||||
|
# Get pdf-dimensions in cm |
||||
|
pdffile = PdfFileReader(open(name+'.pdf', mode='rb')) |
||||
|
pdfsize = np.array([float(pdffile.getPage(0).mediaBox[2]), |
||||
|
float(pdffile.getPage(0).mediaBox[3])]) |
||||
|
pdfdim = pdfsize*2.54/72. # points to cm |
||||
|
|
||||
|
# Define `print`-precision on desired precision |
||||
|
pprec = abs(int(('%.1e' % precision).split('e')[1]))+1 |
||||
|
|
||||
|
# Get difference btw desired and actual size |
||||
|
diff = dsize-pdfdim |
||||
|
|
||||
|
# If diff>precision, adjust, else finish |
||||
|
if np.any(abs(diff) > precision): |
||||
|
if not _cf: |
||||
|
_cf = [1, 1] |
||||
|
|
||||
|
# Be verbose |
||||
|
print(' resize...') |
||||
|
|
||||
|
# Adjust width |
||||
|
if (abs(diff[0]) > precision): |
||||
|
print(' X-diff:', np.round(diff[0], pprec), 'cm') |
||||
|
|
||||
|
# Set new factor to old factor times (desired size)/(actual size) |
||||
|
_cf[0] = _cf[0]*dsize[0]/pdfdim[0] |
||||
|
|
||||
|
# Set new figure width |
||||
|
fhndl.set_figwidth(_cf[0]*dsize[0]/2.54) # cm2in |
||||
|
|
||||
|
# Adjust height |
||||
|
if (abs(diff[1]) > precision): |
||||
|
print(' Y-diff:', np.round(diff[1], pprec), 'cm') |
||||
|
|
||||
|
# Set new factor to old factor times (desired size)/(actual size) |
||||
|
_cf[1] = _cf[1]*dsize[1]/pdfdim[1] |
||||
|
|
||||
|
# Set new figure height |
||||
|
fhndl.set_figheight(_cf[1]*dsize[1]/2.54) #cm2in |
||||
|
|
||||
|
# Call the function again, with new factor _cf |
||||
|
figsize = checksize(fhndl, name, dsize, precision, extent, kwargs, _cf) |
||||
|
|
||||
|
return figsize |
||||
|
|
||||
|
else: # Print some info if the desired dimensions are reached |
||||
|
|
||||
|
# Print figure name and pdf dimensions |
||||
|
print('Figure saved to '+name +'.pdf;', |
||||
|
np.round(pdfdim[0], pprec), 'x', |
||||
|
np.round(pdfdim[1], pprec), 'cm.') |
||||
|
|
||||
|
# Print the new figsize if it had to be adjusted |
||||
|
if _cf: |
||||
|
print(' => NEW FIG-SIZE: figsize=('+ |
||||
|
str(np.round(fhndl.get_size_inches()[0], 2*pprec))+', '+ |
||||
|
str(np.round(fhndl.get_size_inches()[1], 2*pprec))+')') |
||||
|
|
||||
|
# Return figsize |
||||
|
return fhndl.get_size_inches() |
||||
|
|
||||
|
|
||||
|
# In[6]: |
||||
|
|
||||
|
def cm2in(length, decimals=2): |
||||
|
"""Convert cm to inch. |
||||
|
|
||||
|
Parameters |
||||
|
---------- |
||||
|
length : scalar or vector |
||||
|
Numbers to be converted. |
||||
|
decimals : int, optional; <2> |
||||
|
As in np.round, used to round the result. |
||||
|
|
||||
|
Returns |
||||
|
------- |
||||
|
cm2in : scalar or vector |
||||
|
Converted numbers. |
||||
|
|
||||
|
Examples |
||||
|
-------- |
||||
|
>>> from adashof import cm2in |
||||
|
>>> cm2in(5) |
||||
|
1.97 |
||||
|
|
||||
|
""" |
||||
|
|
||||
|
# Test input |
||||
|
try: |
||||
|
length = np.array(length, dtype='float') |
||||
|
decimals = int(decimals) |
||||
|
except ValueError: |
||||
|
print("{length} must be a number, {decimals} an integer") |
||||
|
|
||||
|
return np.round(length/2.54, decimals) |
Write
Preview
Loading…
Cancel
Save
Reference in new issue