Initial commit
This commit is contained in:
197
skills/scientific-visualization/assets/color_palettes.py
Normal file
197
skills/scientific-visualization/assets/color_palettes.py
Normal file
@@ -0,0 +1,197 @@
|
||||
"""
|
||||
Colorblind-Friendly Color Palettes for Scientific Visualization
|
||||
|
||||
This module provides carefully curated color palettes optimized for
|
||||
scientific publications and accessibility.
|
||||
|
||||
Usage:
|
||||
from color_palettes import OKABE_ITO, apply_palette
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
apply_palette('okabe_ito')
|
||||
plt.plot([1, 2, 3], [1, 4, 9])
|
||||
"""
|
||||
|
||||
# Okabe-Ito Palette (2008)
|
||||
# The most widely recommended colorblind-friendly palette
|
||||
OKABE_ITO = {
|
||||
'orange': '#E69F00',
|
||||
'sky_blue': '#56B4E9',
|
||||
'bluish_green': '#009E73',
|
||||
'yellow': '#F0E442',
|
||||
'blue': '#0072B2',
|
||||
'vermillion': '#D55E00',
|
||||
'reddish_purple': '#CC79A7',
|
||||
'black': '#000000'
|
||||
}
|
||||
|
||||
OKABE_ITO_LIST = ['#E69F00', '#56B4E9', '#009E73', '#F0E442',
|
||||
'#0072B2', '#D55E00', '#CC79A7', '#000000']
|
||||
|
||||
# Wong Palette (Nature Methods)
|
||||
WONG = ['#000000', '#E69F00', '#56B4E9', '#009E73',
|
||||
'#F0E442', '#0072B2', '#D55E00', '#CC79A7']
|
||||
|
||||
# Paul Tol Palettes (https://personal.sron.nl/~pault/)
|
||||
TOL_BRIGHT = ['#4477AA', '#EE6677', '#228833', '#CCBB44',
|
||||
'#66CCEE', '#AA3377', '#BBBBBB']
|
||||
|
||||
TOL_MUTED = ['#332288', '#88CCEE', '#44AA99', '#117733',
|
||||
'#999933', '#DDCC77', '#CC6677', '#882255', '#AA4499']
|
||||
|
||||
TOL_LIGHT = ['#77AADD', '#EE8866', '#EEDD88', '#FFAABB',
|
||||
'#99DDFF', '#44BB99', '#BBCC33', '#AAAA00', '#DDDDDD']
|
||||
|
||||
TOL_HIGH_CONTRAST = ['#004488', '#DDAA33', '#BB5566']
|
||||
|
||||
# Sequential colormaps (for continuous data)
|
||||
SEQUENTIAL_COLORMAPS = [
|
||||
'viridis', # Default, perceptually uniform
|
||||
'plasma', # Perceptually uniform
|
||||
'inferno', # Perceptually uniform
|
||||
'magma', # Perceptually uniform
|
||||
'cividis', # Optimized for colorblind viewers
|
||||
'YlOrRd', # Yellow-Orange-Red
|
||||
'YlGnBu', # Yellow-Green-Blue
|
||||
'Blues', # Single hue
|
||||
'Greens', # Single hue
|
||||
'Purples', # Single hue
|
||||
]
|
||||
|
||||
# Diverging colormaps (for data with meaningful center)
|
||||
DIVERGING_COLORMAPS_SAFE = [
|
||||
'RdYlBu', # Red-Yellow-Blue (reversed is common)
|
||||
'RdBu', # Red-Blue
|
||||
'PuOr', # Purple-Orange (excellent for colorblind)
|
||||
'BrBG', # Brown-Blue-Green (good for colorblind)
|
||||
'PRGn', # Purple-Green (use with caution)
|
||||
'PiYG', # Pink-Yellow-Green (use with caution)
|
||||
]
|
||||
|
||||
# Diverging colormaps to AVOID (red-green combinations)
|
||||
DIVERGING_COLORMAPS_AVOID = [
|
||||
'RdGn', # Red-Green (problematic!)
|
||||
'RdYlGn', # Red-Yellow-Green (problematic!)
|
||||
]
|
||||
|
||||
# Fluorophore colors (traditional - use with caution)
|
||||
FLUOROPHORES_TRADITIONAL = {
|
||||
'DAPI': '#0000FF', # Blue
|
||||
'GFP': '#00FF00', # Green (problematic for colorblind)
|
||||
'RFP': '#FF0000', # Red
|
||||
'Cy5': '#FF00FF', # Magenta
|
||||
'YFP': '#FFFF00', # Yellow
|
||||
}
|
||||
|
||||
# Fluorophore colors (colorblind-friendly alternatives)
|
||||
FLUOROPHORES_ACCESSIBLE = {
|
||||
'Channel1': '#0072B2', # Blue
|
||||
'Channel2': '#E69F00', # Orange (instead of green)
|
||||
'Channel3': '#D55E00', # Vermillion (instead of red)
|
||||
'Channel4': '#CC79A7', # Magenta
|
||||
'Channel5': '#F0E442', # Yellow
|
||||
}
|
||||
|
||||
# Genomics/Bioinformatics
|
||||
DNA_BASES = {
|
||||
'A': '#00CC00', # Green
|
||||
'C': '#0000CC', # Blue
|
||||
'G': '#FFB300', # Orange
|
||||
'T': '#CC0000', # Red
|
||||
}
|
||||
|
||||
DNA_BASES_ACCESSIBLE = {
|
||||
'A': '#009E73', # Bluish Green
|
||||
'C': '#0072B2', # Blue
|
||||
'G': '#E69F00', # Orange
|
||||
'T': '#D55E00', # Vermillion
|
||||
}
|
||||
|
||||
|
||||
def apply_palette(palette_name='okabe_ito'):
|
||||
"""
|
||||
Apply a color palette to matplotlib's default color cycle.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
palette_name : str
|
||||
Name of the palette to apply. Options:
|
||||
'okabe_ito', 'wong', 'tol_bright', 'tol_muted',
|
||||
'tol_light', 'tol_high_contrast'
|
||||
|
||||
Returns
|
||||
-------
|
||||
list
|
||||
List of colors in the palette
|
||||
|
||||
Examples
|
||||
--------
|
||||
>>> apply_palette('okabe_ito')
|
||||
>>> plt.plot([1, 2, 3], [1, 4, 9]) # Uses Okabe-Ito colors
|
||||
"""
|
||||
try:
|
||||
import matplotlib.pyplot as plt
|
||||
except ImportError:
|
||||
print("matplotlib not installed")
|
||||
return None
|
||||
|
||||
palettes = {
|
||||
'okabe_ito': OKABE_ITO_LIST,
|
||||
'wong': WONG,
|
||||
'tol_bright': TOL_BRIGHT,
|
||||
'tol_muted': TOL_MUTED,
|
||||
'tol_light': TOL_LIGHT,
|
||||
'tol_high_contrast': TOL_HIGH_CONTRAST,
|
||||
}
|
||||
|
||||
if palette_name not in palettes:
|
||||
available = ', '.join(palettes.keys())
|
||||
raise ValueError(f"Palette '{palette_name}' not found. Available: {available}")
|
||||
|
||||
colors = palettes[palette_name]
|
||||
plt.rcParams['axes.prop_cycle'] = plt.cycler(color=colors)
|
||||
return colors
|
||||
|
||||
|
||||
def get_palette(palette_name='okabe_ito'):
|
||||
"""
|
||||
Get a color palette as a list.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
palette_name : str
|
||||
Name of the palette
|
||||
|
||||
Returns
|
||||
-------
|
||||
list
|
||||
List of color hex codes
|
||||
"""
|
||||
palettes = {
|
||||
'okabe_ito': OKABE_ITO_LIST,
|
||||
'wong': WONG,
|
||||
'tol_bright': TOL_BRIGHT,
|
||||
'tol_muted': TOL_MUTED,
|
||||
'tol_light': TOL_LIGHT,
|
||||
'tol_high_contrast': TOL_HIGH_CONTRAST,
|
||||
}
|
||||
|
||||
if palette_name not in palettes:
|
||||
available = ', '.join(palettes.keys())
|
||||
raise ValueError(f"Palette '{palette_name}' not found. Available: {available}")
|
||||
|
||||
return palettes[palette_name]
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("Available colorblind-friendly palettes:")
|
||||
print(f" - Okabe-Ito: {len(OKABE_ITO_LIST)} colors")
|
||||
print(f" - Wong: {len(WONG)} colors")
|
||||
print(f" - Tol Bright: {len(TOL_BRIGHT)} colors")
|
||||
print(f" - Tol Muted: {len(TOL_MUTED)} colors")
|
||||
print(f" - Tol Light: {len(TOL_LIGHT)} colors")
|
||||
print(f" - Tol High Contrast: {len(TOL_HIGH_CONTRAST)} colors")
|
||||
|
||||
print("\nOkabe-Ito palette (most recommended):")
|
||||
for name, color in OKABE_ITO.items():
|
||||
print(f" {name:15s}: {color}")
|
||||
63
skills/scientific-visualization/assets/nature.mplstyle
Normal file
63
skills/scientific-visualization/assets/nature.mplstyle
Normal file
@@ -0,0 +1,63 @@
|
||||
# Nature journal style
|
||||
# Usage: plt.style.use('nature.mplstyle')
|
||||
#
|
||||
# Optimized for Nature journal specifications:
|
||||
# - Single column: 89 mm
|
||||
# - Double column: 183 mm
|
||||
# - High resolution requirements
|
||||
|
||||
# Figure properties
|
||||
figure.dpi: 100
|
||||
figure.facecolor: white
|
||||
figure.constrained_layout.use: True
|
||||
figure.figsize: 3.5, 2.625 # 89 mm single column, 3:4 aspect
|
||||
|
||||
# Font properties (Nature prefers smaller fonts)
|
||||
font.size: 7
|
||||
font.family: sans-serif
|
||||
font.sans-serif: Arial, Helvetica
|
||||
|
||||
# Axes properties
|
||||
axes.linewidth: 0.5
|
||||
axes.labelsize: 8
|
||||
axes.titlesize: 8
|
||||
axes.labelweight: normal
|
||||
axes.spines.top: False
|
||||
axes.spines.right: False
|
||||
axes.edgecolor: black
|
||||
axes.axisbelow: True
|
||||
axes.grid: False
|
||||
axes.prop_cycle: cycler('color', ['E69F00', '56B4E9', '009E73', 'F0E442', '0072B2', 'D55E00', 'CC79A7'])
|
||||
|
||||
# Tick properties
|
||||
xtick.major.size: 2.5
|
||||
xtick.minor.size: 1.5
|
||||
xtick.major.width: 0.5
|
||||
xtick.minor.width: 0.4
|
||||
xtick.labelsize: 6
|
||||
xtick.direction: out
|
||||
ytick.major.size: 2.5
|
||||
ytick.minor.size: 1.5
|
||||
ytick.major.width: 0.5
|
||||
ytick.minor.width: 0.4
|
||||
ytick.labelsize: 6
|
||||
ytick.direction: out
|
||||
|
||||
# Line properties
|
||||
lines.linewidth: 1.2
|
||||
lines.markersize: 3
|
||||
lines.markeredgewidth: 0.4
|
||||
|
||||
# Legend properties
|
||||
legend.fontsize: 6
|
||||
legend.frameon: False
|
||||
|
||||
# Save properties (Nature requirements)
|
||||
savefig.dpi: 600 # 1000 for line art, 600 for combination
|
||||
savefig.format: pdf
|
||||
savefig.bbox: tight
|
||||
savefig.pad_inches: 0.05
|
||||
savefig.facecolor: white
|
||||
|
||||
# Image properties
|
||||
image.cmap: viridis
|
||||
61
skills/scientific-visualization/assets/presentation.mplstyle
Normal file
61
skills/scientific-visualization/assets/presentation.mplstyle
Normal file
@@ -0,0 +1,61 @@
|
||||
# Presentation/Poster style
|
||||
# Usage: plt.style.use('presentation.mplstyle')
|
||||
#
|
||||
# Larger fonts and thicker lines for presentations,
|
||||
# posters, and projected displays
|
||||
|
||||
# Figure properties
|
||||
figure.dpi: 100
|
||||
figure.facecolor: white
|
||||
figure.constrained_layout.use: True
|
||||
figure.figsize: 8, 6
|
||||
|
||||
# Font properties (larger for visibility)
|
||||
font.size: 14
|
||||
font.family: sans-serif
|
||||
font.sans-serif: Arial, Helvetica, Calibri
|
||||
|
||||
# Axes properties
|
||||
axes.linewidth: 1.5
|
||||
axes.labelsize: 16
|
||||
axes.titlesize: 18
|
||||
axes.labelweight: normal
|
||||
axes.spines.top: False
|
||||
axes.spines.right: False
|
||||
axes.edgecolor: black
|
||||
axes.axisbelow: True
|
||||
axes.grid: False
|
||||
axes.prop_cycle: cycler('color', ['E69F00', '56B4E9', '009E73', 'F0E442', '0072B2', 'D55E00', 'CC79A7'])
|
||||
|
||||
# Tick properties
|
||||
xtick.major.size: 6
|
||||
xtick.minor.size: 4
|
||||
xtick.major.width: 1.5
|
||||
xtick.minor.width: 1.0
|
||||
xtick.labelsize: 12
|
||||
xtick.direction: out
|
||||
ytick.major.size: 6
|
||||
ytick.minor.size: 4
|
||||
ytick.major.width: 1.5
|
||||
ytick.minor.width: 1.0
|
||||
ytick.labelsize: 12
|
||||
ytick.direction: out
|
||||
|
||||
# Line properties
|
||||
lines.linewidth: 2.5
|
||||
lines.markersize: 8
|
||||
lines.markeredgewidth: 1.0
|
||||
|
||||
# Legend properties
|
||||
legend.fontsize: 12
|
||||
legend.frameon: False
|
||||
|
||||
# Save properties
|
||||
savefig.dpi: 300
|
||||
savefig.format: png
|
||||
savefig.bbox: tight
|
||||
savefig.pad_inches: 0.1
|
||||
savefig.facecolor: white
|
||||
|
||||
# Image properties
|
||||
image.cmap: viridis
|
||||
68
skills/scientific-visualization/assets/publication.mplstyle
Normal file
68
skills/scientific-visualization/assets/publication.mplstyle
Normal file
@@ -0,0 +1,68 @@
|
||||
# Publication-quality matplotlib style
|
||||
# Usage: plt.style.use('publication.mplstyle')
|
||||
#
|
||||
# This style provides clean, professional formatting suitable
|
||||
# for most scientific journals
|
||||
|
||||
# Figure properties
|
||||
figure.dpi: 100
|
||||
figure.facecolor: white
|
||||
figure.autolayout: False
|
||||
figure.constrained_layout.use: True
|
||||
figure.figsize: 3.5, 2.5
|
||||
|
||||
# Font properties
|
||||
font.size: 8
|
||||
font.family: sans-serif
|
||||
font.sans-serif: Arial, Helvetica, DejaVu Sans
|
||||
|
||||
# Axes properties
|
||||
axes.linewidth: 0.5
|
||||
axes.labelsize: 9
|
||||
axes.titlesize: 9
|
||||
axes.labelweight: normal
|
||||
axes.spines.top: False
|
||||
axes.spines.right: False
|
||||
axes.spines.left: True
|
||||
axes.spines.bottom: True
|
||||
axes.edgecolor: black
|
||||
axes.labelcolor: black
|
||||
axes.axisbelow: True
|
||||
axes.grid: False
|
||||
axes.prop_cycle: cycler('color', ['E69F00', '56B4E9', '009E73', 'F0E442', '0072B2', 'D55E00', 'CC79A7', '000000'])
|
||||
|
||||
# Tick properties
|
||||
xtick.major.size: 3
|
||||
xtick.minor.size: 2
|
||||
xtick.major.width: 0.5
|
||||
xtick.minor.width: 0.5
|
||||
xtick.labelsize: 7
|
||||
xtick.direction: out
|
||||
ytick.major.size: 3
|
||||
ytick.minor.size: 2
|
||||
ytick.major.width: 0.5
|
||||
ytick.minor.width: 0.5
|
||||
ytick.labelsize: 7
|
||||
ytick.direction: out
|
||||
|
||||
# Line properties
|
||||
lines.linewidth: 1.5
|
||||
lines.markersize: 4
|
||||
lines.markeredgewidth: 0.5
|
||||
|
||||
# Legend properties
|
||||
legend.fontsize: 7
|
||||
legend.frameon: False
|
||||
legend.loc: best
|
||||
|
||||
# Save properties
|
||||
savefig.dpi: 300
|
||||
savefig.format: pdf
|
||||
savefig.bbox: tight
|
||||
savefig.pad_inches: 0.05
|
||||
savefig.transparent: False
|
||||
savefig.facecolor: white
|
||||
|
||||
# Image properties
|
||||
image.cmap: viridis
|
||||
image.aspect: auto
|
||||
Reference in New Issue
Block a user