Skip to content

Instantly share code, notes, and snippets.

@tacaswell
Created November 15, 2022 21:27
Show Gist options
  • Save tacaswell/1a64796569a4980f7fdb853d98e6c980 to your computer and use it in GitHub Desktop.
Save tacaswell/1a64796569a4980f7fdb853d98e6c980 to your computer and use it in GitHub Desktop.
two slope scale for Matplotlib
import itertools
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.scale as mscale
def factory(break_point, slope_ratio):
def forward(values):
out = np.array(values, copy=True)
out -= break_point
out[out>0] *= slope_ratio
out += break_point
return out
def inverse(values):
out = np.array(values, copy=True)
out -= break_point
out[out>0] /= slope_ratio
out += break_point
return out
return forward, inverse
def demo_plot(ax):
ax.plot(x,x, '-o', label='linear')
ax.plot(x,x*x, '-o', label='quadratic')
ax.plot(x,np.sin(x*5), '-o', label='sin')
x = np.linspace(0, 10, 50)
fig, axs = plt.subplots(2, 2, layout='constrained', figsize=(10, 10))
y_ratio = 1/10
x_ratio = 1/5
for ((x_break, y_break), ax) in zip(itertools.product([1, 5], [5, 50]), axs.flat):
fcx = mscale.FuncScale(None, factory(x_break, x_ratio))
fcy = mscale.FuncScale(None, factory(y_break, y_ratio))
ax.axvline(x_break, color='k')
ax.set_xscale(fcx)
ax.axhline(y_break, color='k')
ax.set_yscale(fcy)
demo_plot(ax)
ax.set_title(f'{x_break=}, {y_break=}, {x_ratio=}, {y_ratio=}')
fig, axs = plt.subplots(2, 2, layout='constrained', figsize=(10, 10))
y_break = 50
x_break = 5
for ((x_ratio, y_ratio), ax) in zip(itertools.product([5, 1/5], [5, 1/5]), axs.flat):
fcx = mscale.FuncScale(None, factory(x_break, x_ratio))
fcy = mscale.FuncScale(None, factory(y_break, y_ratio))
ax.axvline(x_break, color='k')
ax.set_xscale(fcx)
ax.axhline(y_break, color='k')
ax.set_yscale(fcy)
demo_plot(ax)
ax.set_title(f'{x_break=}, {y_break=}, {x_ratio=}, {y_ratio=}')
plt.show()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment