I have a plot a bit like this:
The differences between the two lines (red and blue) are most important in my actual data (a ROC curve) at say the grid cell 0.2<x<0.4
, 0.8<y<1
. Now, I could crop for that grid cell, but let's say I'd rather scale both the x and y axes hyperbolically -- where the y-axis hyperbolic curve has its peak at about 0.9 and the x-axis has its peak at about 0.3 -- such that the 2D space gets stretched out for the grid cell of interest and gets compacted elsewhere (and preserving the meaning of the axes tick numbers). How would one accomplish this? The beginnings of my attempt are below. How would my code be modified to implement the axis scaling I described?
from matplotlib import gridspec
from matplotlib import scale as mscale
from matplotlib import transforms as mtransforms
from matplotlib.ticker import FormatStrFormatter
from matplotlib.ticker import NullFormatter, NullLocator, MultipleLocator
import math
import matplotlib
import matplotlib.patches as mpatches
import matplotlib.pylab as plt
import matplotlib.pyplot as plt
import matplotlib.ticker
import numpy as np
import seaborn as sns
sns.set_palette('husl')
sns.set()
plt.rcParams["figure.figsize"] = [5, 5]
x = np.arange(0, 1, step=0.01)
y1 = 1-1/np.exp(10*x)
y2 = 1-1.1/np.exp(10*x)
plt.scatter(x, y1, s=1, facecolor='red')
plt.scatter(x, y2, s=1, facecolor='blue')
plt.show();
class CustomScale(mscale.ScaleBase):
name = 'custom'
def __init__(self, axis, **kwargs):
mscale.ScaleBase.__init__(self)
self.thresh = None #thresh
self.name = 'custom'
def get_transform(self):
return self.CustomTransform(self.thresh)
def set_default_locators_and_formatters(self, axis):
pass
class CustomTransform(mtransforms.Transform):
input_dims = 1
output_dims = 1
is_separable = True
def __init__(self, thresh):
mtransforms.Transform.__init__(self)
self.thresh = thresh
def transform_non_affine(self, a):
#return np.log(1+a)
return np.exp(a)-1
#return 1+(1/2)*a
mscale.register_scale(CustomScale)
plt.scatter(x, y1, s=1, facecolor='red')
plt.scatter(x, y2, s=1, facecolor='blue')
plt.xscale('custom')
plt.show();