Skip to content

Commit

Permalink
datanal
Browse files Browse the repository at this point in the history
  • Loading branch information
FridrichMethod authored Mar 17, 2024
1 parent 4c07843 commit 2329788
Show file tree
Hide file tree
Showing 8 changed files with 1,406 additions and 2 deletions.
45 changes: 45 additions & 0 deletions GraphPadPrism.mplstyle
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
axes.autolimit_mode: round_numbers
axes.labelsize: 12
axes.labelweight: bold
axes.linewidth: 1.5
axes.spines.right: False
axes.spines.top: False
axes.titlesize: 16
axes.titleweight: bold

errorbar.capsize: 3

figure.dpi: 300
figure.figsize: 4.5, 3
figure.frameon: False

font.sans-serif: Arial, sans-serif
font.size: 14
font.weight: bold

legend.fontsize: 8
legend.frameon: False
legend.loc: upper right

lines.linewidth: 2
lines.markeredgecolor: black
lines.markerfacecolor: black

mathtext.bf: Arial:bold
mathtext.bfit: Arial:italic:bold
mathtext.fontset: custom
mathtext.it: Arial:italic
mathtext.rm: Arial
mathtext.sf: Arial

savefig.bbox: tight

xtick.labelsize: 10
xtick.major.width: 1.5
xtick.minor.visible: True
xtick.minor.width: 1.5

ytick.labelsize: 10
ytick.major.width: 1.5
ytick.minor.visible: True
ytick.minor.width: 1.5
2 changes: 0 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +0,0 @@
# datanal
A Python package for data analysis and visualization.
19 changes: 19 additions & 0 deletions __init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
"""datanal: A Python package for data analysis and visualization.
datanal is a Python package for data analysis and visualization.
It is designed to be used in conjunction with matplotlib and seaborn to create publication-quality figures.
The package is developed and maintained by Zhaoyang Li.
If you have any questions or suggestions, please feel free to contact me at [email protected].
Modules
-------
datanal.enz: A module for enzyme activity data analysis
datanal.mst: A module for microscale thermophoresis (MST) data analysis
datanal.spr: A module for surface plasmon resonance (SPR) data analysis
datanal.itc: A module for isothermal titration calorimetry (ITC) data analysis
"""

__version__ = "1.2.0"
__author__ = "Zhaoyang Li"
__email__ = "[email protected]"
129 changes: 129 additions & 0 deletions _utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
"""Utility functions for the datanal package."""

from typing import Any
from warnings import warn

import matplotlib.pyplot as plt
import seaborn as sns
from matplotlib import ticker
from matplotlib.axes import Axes


def auto_style(
rc_mplstyle: dict[str, Any] | None = None,
fname_mplstyle: str | None = None,
palette_snsstyle: str | list[str] | None = None,
) -> None:
"""Initialize the matplotlib and seaborn styles.
Parameters
----------
rc_mplstyle : dict[str, Any] | None
The matplotlib style for rcParams.
fname_mplstyle : str | None
The matplotlib style for figure.
palette_snsstyle : str | list[str] | None
The seaborn style for palette.
Returns
-------
None
"""
import datanal # NECESSARY for importing the custom styles

plt.style.use("datanal.GraphPadPrism")
sns.set_palette("bright")

if palette_snsstyle is not None:
sns.set_palette(palette_snsstyle)
if fname_mplstyle is not None:
plt.style.use(fname_mplstyle)
if rc_mplstyle is not None:
plt.style.use(rc_mplstyle)


def auto_ticks(
ax: Axes,
*,
x_lim: tuple[float, float] | None = None,
y_lim: tuple[float, float] | None = None,
) -> None:
"""Set the major and minor ticks of an axis automatically.
Parameters
----------
ax : Axes
The axis to be set.
x_lim : tuple[float, float] | None, optional
The limits of the x-axis, by default None.
y_lim : tuple[float, float] | None, optional
The limits of the y-axis, by default None.
Returns
-------
None
"""

if x_lim is not None:
ax.set_xlim(x_lim)
ax.xaxis.set_major_locator(ticker.MaxNLocator(nbins=6, min_n_ticks=3))
x_tick_num = len(ax.get_xticks())
if x_tick_num >= 6:
ax.xaxis.set_minor_locator(ticker.AutoMinorLocator(2))
elif x_tick_num >= 5:
ax.xaxis.set_minor_locator(ticker.AutoMinorLocator(4))
else:
ax.xaxis.set_minor_locator(ticker.AutoMinorLocator(5))

if y_lim is not None:
ax.set_ylim(y_lim)
ax.yaxis.set_major_locator(ticker.MaxNLocator(nbins=6, min_n_ticks=3))
y_tick_num = len(ax.get_yticks())
if y_tick_num >= 6:
ax.yaxis.set_minor_locator(ticker.AutoMinorLocator(2))
elif y_tick_num >= 5:
ax.yaxis.set_minor_locator(ticker.AutoMinorLocator(4))
else:
ax.yaxis.set_minor_locator(ticker.AutoMinorLocator(5))


def auto_units(quant: float, old_unit: str = "M") -> tuple[str, float]:
"""Convert a quantity to a more appropriate unit.
Parameters
----------
quant : float
The quantity to be converted.
old_unit : str, optional
The unit of the quantity, by default "M".
Returns
-------
tuple[str, float]
The converted unit and the conversion factor.
"""

units = {
"M": (1, 2e-1),
"mM": (1e-3, 2e-4),
"μM": (1e-6, 2e-7),
"nM": (1e-9, 2e-10),
"pM": (1e-12, 2e-13),
"fM": (1e-15, 2e-16),
}

if old_unit not in units:
warn(f"Unknown unit {old_unit} was detected.")
return old_unit, 1

old_scale = units[old_unit][0]
quant *= old_scale

return next(
(
(new_unit, old_scale / new_scale)
for new_unit, (new_scale, bound) in units.items()
if quant >= bound
),
(old_unit, 1),
)
Loading

0 comments on commit 2329788

Please sign in to comment.