Dav*_*ker 12 python matplotlib
我使用matplotlib的symlog标度来覆盖向正方向和负方向延伸的大范围参数.不幸的是,symlog规模不是很直观,也可能不常用.因此,我想通过在主要刻度之间放置小刻度来使用过的缩放更明显.在比例的日志部分,我想在[2,3,...,9]*10 ^ e处放置蜱,其中e是附近的主要蜱.此外,0到0.1之间的范围应覆盖均匀放置的次要刻度,相隔0.01.我尝试使用matplotlib.ticker API使用以下代码获得此类滴答:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.ticker import LogLocator, AutoLocator
x = np.linspace(-5, 5, 100)
y = x
plt.plot(x, y)
plt.yscale('symlog', linthreshy=1e-1)
yaxis = plt.gca().yaxis
yaxis.set_minor_locator(LogLocator(subs=np.arange(2, 10)))
plt.show()
Run Code Online (Sandbox Code Playgroud)
不幸的是,这不会产生我想要的东西:

请注意,在0附近有许多小的刻度,这可能是由于LogLocator.此外,负轴上没有小的刻度.
如果我使用而AutoLocator不是出现轻微的刻度.该AutoMinorLocator不会只支持按比例均匀轴.我的问题是如何实现所需的刻度位置?
Dav*_*ker 13
深入研究这个问题,我注意到很难找到一个通用的解决方案.幸运的是,我可以假设我的数据受到一些限制,因此定制的类足以解决问题:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.ticker import Locator
class MinorSymLogLocator(Locator):
"""
Dynamically find minor tick positions based on the positions of
major ticks for a symlog scaling.
"""
def __init__(self, linthresh):
"""
Ticks will be placed between the major ticks.
The placement is linear for x between -linthresh and linthresh,
otherwise its logarithmically
"""
self.linthresh = linthresh
def __call__(self):
'Return the locations of the ticks'
majorlocs = self.axis.get_majorticklocs()
# iterate through minor locs
minorlocs = []
# handle the lowest part
for i in xrange(1, len(majorlocs)):
majorstep = majorlocs[i] - majorlocs[i-1]
if abs(majorlocs[i-1] + majorstep/2) < self.linthresh:
ndivs = 10
else:
ndivs = 9
minorstep = majorstep / ndivs
locs = np.arange(majorlocs[i-1], majorlocs[i], minorstep)[1:]
minorlocs.extend(locs)
return self.raise_if_exceeds(np.array(minorlocs))
def tick_values(self, vmin, vmax):
raise NotImplementedError('Cannot get tick locations for a '
'%s type.' % type(self))
x = np.linspace(-5, 5, 100)
y = x
plt.plot(x, y)
plt.yscale('symlog', linthreshy=1e-1)
yaxis = plt.gca().yaxis
yaxis.set_minor_locator(MinorSymLogLocator(1e-1))
plt.show()
Run Code Online (Sandbox Code Playgroud)
这产生了

请注意,此方法仅在主要刻度之间放置刻度.如果您缩放并平移图像,这将变得明显.此外,线性阈值必须明确地提供给类,因为我发现无法从轴本身轻松而稳健地读取它.
OPs 解决方案效果很好,但如果轴的边缘不是线性阈值的倍数,则不会在轴的边缘产生刻度线。我对 OPsMinorSymLogLocator()类进行了修改,给出了以下内容(通过在设置次要刻度位置时添加临时主要刻度位置来填充边缘):
class MinorSymLogLocator(Locator):
"""
Dynamically find minor tick positions based on the positions of
major ticks for a symlog scaling.
"""
def __init__(self, linthresh, nints=10):
"""
Ticks will be placed between the major ticks.
The placement is linear for x between -linthresh and linthresh,
otherwise its logarithmically. nints gives the number of
intervals that will be bounded by the minor ticks.
"""
self.linthresh = linthresh
self.nintervals = nints
def __call__(self):
# Return the locations of the ticks
majorlocs = self.axis.get_majorticklocs()
if len(majorlocs) == 1:
return self.raise_if_exceeds(np.array([]))
# add temporary major tick locs at either end of the current range
# to fill in minor tick gaps
dmlower = majorlocs[1] - majorlocs[0] # major tick difference at lower end
dmupper = majorlocs[-1] - majorlocs[-2] # major tick difference at upper end
# add temporary major tick location at the lower end
if majorlocs[0] != 0. and ((majorlocs[0] != self.linthresh and dmlower > self.linthresh) or (dmlower == self.linthresh and majorlocs[0] < 0)):
majorlocs = np.insert(majorlocs, 0, majorlocs[0]*10.)
else:
majorlocs = np.insert(majorlocs, 0, majorlocs[0]-self.linthresh)
# add temporary major tick location at the upper end
if majorlocs[-1] != 0. and ((np.abs(majorlocs[-1]) != self.linthresh and dmupper > self.linthresh) or (dmupper == self.linthresh and majorlocs[-1] > 0)):
majorlocs = np.append(majorlocs, majorlocs[-1]*10.)
else:
majorlocs = np.append(majorlocs, majorlocs[-1]+self.linthresh)
# iterate through minor locs
minorlocs = []
# handle the lowest part
for i in xrange(1, len(majorlocs)):
majorstep = majorlocs[i] - majorlocs[i-1]
if abs(majorlocs[i-1] + majorstep/2) < self.linthresh:
ndivs = self.nintervals
else:
ndivs = self.nintervals - 1.
minorstep = majorstep / ndivs
locs = np.arange(majorlocs[i-1], majorlocs[i], minorstep)[1:]
minorlocs.extend(locs)
return self.raise_if_exceeds(np.array(minorlocs))
def tick_values(self, vmin, vmax):
raise NotImplementedError('Cannot get tick locations for a '
'%s type.' % type(self))
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3089 次 |
| 最近记录: |