Show the code
import matplotlib.pyplot as plt
import seaborn as sns
# Just import maidr package: plt.show() now renders accessible output
import maidr
# The scatter plot below reuses this dataset.
iris = sns.load_dataset("iris")A scatter plot is read point by point in x order: the Left and Right arrows move across the points, each stop announces its x and y (and its hue group when one is set), and the pitch follows y. A regression plot adds a fitted line, which py-maidr exposes as a second layer: Page Up and Page Down switch between the points and the smooth curve, so the trend can be heard on its own and then checked against the scatter.
SCATTER and SMOOTH are in the stable set: see Plot Type Stability. The volcano and Manhattan plots at the end of the page are scatters declared as such, VOLCANO and MANHATTAN, which are experimental.
Every example on this page needs only the import below. The plot cells repeat it so each one can be copied on its own.
import matplotlib.pyplot as plt
import seaborn as sns
import maidr
# Create a scatter plot
fig, ax = plt.subplots()
scatter_plot = sns.scatterplot(
data=iris, x="sepal_length", y="sepal_width", hue="species", ax=ax
)
# Adding title and labels
ax.set_title("Iris Sepal Length vs Sepal Width")
ax.set_xlabel("Sepal Length (cm)")
ax.set_ylabel("Sepal Width (cm)")
# Add number formatters for better screen reader output
ax.xaxis.set_major_formatter("{x:.1f}")
ax.yaxis.set_major_formatter("{x:.1f}")
# Show the plot
plt.show() import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
import maidr
# Generate sample data
np.random.seed(42)
x = np.linspace(0, 10, 50)
y = 2 * x + 1 + np.random.normal(0, 2, 50)
# Create a regression plot
fig, ax = plt.subplots(figsize=(6, 6))
reg_plot = sns.regplot(
x=x,
y=y,
scatter_kws={"s": 50, "alpha": 0.7},
line_kws={"color": "red", "lw": 2},
ax=ax,
)
ax.set_title("Regression Plot with Fitted Line")
ax.set_xlabel("X values")
ax.set_ylabel("Y values")
# Add number formatters for better screen reader output
ax.xaxis.set_major_formatter("{x:.1f}")
ax.yaxis.set_major_formatter("{x:.2f}")
plt.show() A volcano plot is a scatter read through a threshold, and nothing in the drawing says where the threshold is, so it is declared: maidr.volcano() takes the scatter, the significance cutoff on y and, optionally, the effect-size cutoff on the magnitude of x, with a name for each point. The chart then opens with how many points clear both cutoffs and which, announces each point’s name, and adds a rotor mode (Alt+Shift+Up) that walks only the points that clear them.
import matplotlib.pyplot as plt
import numpy as np
import maidr
rng = np.random.default_rng(7)
genes = [f"GENE{i:03d}" for i in range(200)]
fold_change = rng.normal(0, 0.8, 200)
minus_log10_p = np.abs(fold_change) * rng.uniform(0.5, 2.5, 200)
fig, ax = plt.subplots()
points = ax.scatter(fold_change, minus_log10_p, s=12)
ax.axhline(1.3, linestyle="--", color="grey")
ax.axvline(-1, linestyle=":", color="grey")
ax.axvline(1, linestyle=":", color="grey")
ax.set_title("Differential expression")
ax.set_xlabel("Log2 fold change")
ax.set_ylabel("-log10 p")
# p < 0.05 and at least a two-fold change, either way
maidr.volcano(points, significance=1.3, effect=1.0, labels=genes)
plt.show() A Manhattan plot is declared the same way with maidr.manhattan(), which also takes each point’s chromosome. It has no effect cutoff, because x is a position on the genome rather than a size. Drawing one scatter per chromosome, as here, is the usual way to alternate their colors; pass them all, and the names and chromosomes in the same order.
import matplotlib.pyplot as plt
import numpy as np
import maidr
rng = np.random.default_rng(11)
fig, ax = plt.subplots(figsize=(8, 4))
drawn, snps, chromosomes, centers = [], [], [], []
start = 0
for number in range(1, 5):
position = start + np.sort(rng.uniform(0, 100, 40))
minus_log10_p = rng.exponential(1.2, 40)
if number == 2:
minus_log10_p[17] = 9.4 # one genome-wide hit
color = "tab:blue" if number % 2 else "tab:grey"
drawn.append(ax.scatter(position, minus_log10_p, s=10, color=color))
snps += [f"rs{number}{i:03d}" for i in range(40)]
chromosomes += [f"chr{number}"] * 40
centers.append(start + 50)
start += 100
ax.axhline(7.3, linestyle="--", color="grey")
ax.set_xticks(centers, [f"chr{n}" for n in range(1, 5)])
ax.set_title("Genome-wide association")
ax.set_xlabel("Genomic position")
ax.set_ylabel("-log10 p")
maidr.manhattan(
drawn, significance=7.3, labels=snps, groups=chromosomes
)
plt.show()