在绘制半对数图时(y是对数),y轴上的小刻度线(十年中有8个)会自动出现,但似乎当轴范围超过10**10时,它们就会消失。我尝试了许多方法来强制它们回来,但都没有用。可能是为了避免过度拥挤,它们会在大范围内消失,但应该有选择吗?
j2datikz1#
让我们考虑下面的例子
它由以下代码生成:
import matplotlib.pyplot as pltimport matplotlib.tickerimport numpy as npy = np.arange(12)x = 10.0**yfig, ax=plt.subplots()ax.plot(x,y)ax.set_xscale("log")plt.show()
import matplotlib.pyplot as plt
import matplotlib.ticker
import numpy as np
y = np.arange(12)
x = 10.0**y
fig, ax=plt.subplots()
ax.plot(x,y)
ax.set_xscale("log")
plt.show()
次要的ticklabel确实消失了,通常显示它们的方法(如plt.tick_params(axis='x', which='minor'))失败了。第一步是在轴上显示10的所有幂,
plt.tick_params(axis='x', which='minor')
locmaj = matplotlib.ticker.LogLocator(base=10,numticks=12) ax.xaxis.set_major_locator(locmaj)
locmaj = matplotlib.ticker.LogLocator(base=10,numticks=12)
ax.xaxis.set_major_locator(locmaj)
其中技巧是将numticks设置为等于或大于滴答数的数字(即在这种情况下为12或更高)。然后,我们可以添加次要的ticklabels,
numticks
locmin = matplotlib.ticker.LogLocator(base=10.0,subs=(0.2,0.4,0.6,0.8),numticks=12)ax.xaxis.set_minor_locator(locmin)ax.xaxis.set_minor_formatter(matplotlib.ticker.NullFormatter())
locmin = matplotlib.ticker.LogLocator(base=10.0,subs=(0.2,0.4,0.6,0.8),numticks=12)
ax.xaxis.set_minor_locator(locmin)
ax.xaxis.set_minor_formatter(matplotlib.ticker.NullFormatter())
请注意,我将其限制为每十年包括4个小刻度(使用8也是同样可能的,但在这个例子中会使轴过度拥挤)。还要注意,numticks再次(非常不直观地)为12或更大。最后,我们需要为次要tick使用NullFormatter(),以便不为它们显示任何ticklabel。
NullFormatter()
locmaj = matplotlib.ticker.LogLocator(base=10.0, subs=(0.1,1.0, ))ax.xaxis.set_major_locator(locmaj)
locmaj = matplotlib.ticker.LogLocator(base=10.0, subs=(0.1,1.0, ))
然后,我们可以添加次要的ticklabels,
locmin = matplotlib.ticker.LogLocator(base=10.0, subs=(0.1,0.2,0.4,0.6,0.8,1,2,4,6,8,10 )) ax.xaxis.set_minor_locator(locmin)ax.xaxis.set_minor_formatter(matplotlib.ticker.NullFormatter())
locmin = matplotlib.ticker.LogLocator(base=10.0, subs=(0.1,0.2,0.4,0.6,0.8,1,2,4,6,8,10 ))
请注意,我限制了每十年包含4个小刻度(使用8也是可能的,但在这个例子中会使轴过度拥挤)。还要注意-这可能是这里的关键-subs参数,它给出了放置刻度的基数的整数幂的倍数(参见文档),给出了一个二十年的列表,而不是一个。最后,我们需要为次要tick使用NullFormatter(),以便不为它们显示任何ticklabel。
subs
fbcarpbf2#
从Matplotlib 3.5.2开始:
subs="auto"
from matplotlib import pyplot as plt, ticker as mtickerfig, ax = plt.subplots()y = np.arange(11)x = 10.0**yax.semilogx(x, y)ax.xaxis.set_major_locator(mticker.LogLocator(numticks=999))ax.xaxis.set_minor_locator(mticker.LogLocator(numticks=999, subs="auto"))
from matplotlib import pyplot as plt, ticker as mticker
fig, ax = plt.subplots()
y = np.arange(11)
ax.semilogx(x, y)
ax.xaxis.set_major_locator(mticker.LogLocator(numticks=999))
ax.xaxis.set_minor_locator(mticker.LogLocator(numticks=999, subs="auto"))
from matplotlib import pyplot as plt, ticker as mtickerfig, ax = plt.subplots()y = np.arange(12)x = 10.0**yax.semilogx(x, y)ax.xaxis.set_major_locator(mticker.LogLocator(numticks=999))ax.xaxis.set_minor_locator(mticker.LogLocator(numticks=999, subs=(.2, .4, .6, .8)))
ax.xaxis.set_minor_locator(mticker.LogLocator(numticks=999, subs=(.2, .4, .6, .8)))
jhdbpxl93#
这里的答案忽略了一个方便的事实,即对数缩放轴已经有了必要的定位器。至少从Matplotlib 3.6开始,使用set_params()的值强制小刻度就足够了:
set_params()
import matplotlib.pyplot as pltimport numpy as npy = np.arange(12)x = 10.0**yfig, ax = plt.subplots()ax.plot(x, y)ax.set_xscale('log')ax.xaxis.get_major_locator().set_params(numticks=99)ax.xaxis.get_minor_locator().set_params(numticks=99, subs=[.2, .4, .6, .8])plt.show()
ax.plot(x, y)
ax.set_xscale('log')
ax.xaxis.get_major_locator().set_params(numticks=99)
ax.xaxis.get_minor_locator().set_params(numticks=99, subs=[.2, .4, .6, .8])
fzwojiic4#
带有空标签的主刻度将生成刻度,但不生成标签。
ax.set_yticks([1.E-6,1.E-5,1.E-4,1.E-3,1.E-2,1.E-1,1.E0,1.E1,1.E2,1.E3,1.E4,1.E5,])ax.set_yticklabels(['$10^{-6}$','','','$10^{-3}$','','','$1$','','','$10^{3}$','',''])
ax.set_yticks([1.E-6,1.E-5,1.E-4,1.E-3,1.E-2,1.E-1,1.E0,1.E1,1.E2,1.E3,1.E4,1.E5,])
ax.set_yticklabels(['$10^{-6}$','','','$10^{-3}$','','','$1$','','','$10^{3}$','',''])
ljo96ir55#
将matplotlib >= 2.0.2的importanceofbeingernest中的excellent answer Package 成一个函数:
matplotlib >= 2.0.2
import matplotlib.pyplot as pltfrom typing import Optionaldef restore_minor_ticks_log_plot( ax: Optional[plt.Axes] = None, n_subticks=9) -> None: """For axes with a logrithmic scale where the span (max-min) exceeds 10 orders of magnitude, matplotlib will not set logarithmic minor ticks. If you don't like this, call this function to restore minor ticks. Args: ax: n_subticks: Number of Should be either 4 or 9. Returns: None """ if ax is None: ax = plt.gca() # Method from SO user importanceofbeingernest at # https://stackoverflow.com/a/44079725/5972175 locmaj = mpl.ticker.LogLocator(base=10, numticks=1000) ax.xaxis.set_major_locator(locmaj) locmin = mpl.ticker.LogLocator( base=10.0, subs=np.linspace(0, 1.0, n_subticks + 2)[1:-1], numticks=1000 ) ax.xaxis.set_minor_locator(locmin) ax.xaxis.set_minor_formatter(mpl.ticker.NullFormatter())
from typing import Optional
def restore_minor_ticks_log_plot(
ax: Optional[plt.Axes] = None, n_subticks=9
) -> None:
"""For axes with a logrithmic scale where the span (max-min) exceeds
10 orders of magnitude, matplotlib will not set logarithmic minor ticks.
If you don't like this, call this function to restore minor ticks.
Args:
ax:
n_subticks: Number of Should be either 4 or 9.
Returns:
None
"""
if ax is None:
ax = plt.gca()
# Method from SO user importanceofbeingernest at
# https://stackoverflow.com/a/44079725/5972175
locmaj = mpl.ticker.LogLocator(base=10, numticks=1000)
locmin = mpl.ticker.LogLocator(
base=10.0, subs=np.linspace(0, 1.0, n_subticks + 2)[1:-1], numticks=1000
)
ax.xaxis.set_minor_formatter(mpl.ticker.NullFormatter())
这个函数可以被称为
plt.plot(x,y)plt.xscale("log")restore_minor_ticks_log_plot()
plt.plot(x,y)
plt.xscale("log")
restore_minor_ticks_log_plot()
或多个明确
_, ax = plt.subplots()ax.plot(x, y)ax.set_xscale("log")restore_minor_ticks_log_plot(ax)
_, ax = plt.subplots()
restore_minor_ticks_log_plot(ax)
5条答案
按热度按时间j2datikz1#
matplotlib >= 2.0.2的解决方案
让我们考虑下面的例子
它由以下代码生成:
次要的ticklabel确实消失了,通常显示它们的方法(如
plt.tick_params(axis='x', which='minor')
)失败了。第一步是在轴上显示10的所有幂,
其中技巧是将
numticks
设置为等于或大于滴答数的数字(即在这种情况下为12或更高)。然后,我们可以添加次要的ticklabels,
请注意,我将其限制为每十年包括4个小刻度(使用8也是同样可能的,但在这个例子中会使轴过度拥挤)。还要注意,
numticks
再次(非常不直观地)为12或更大。最后,我们需要为次要tick使用
NullFormatter()
,以便不为它们显示任何ticklabel。matplotlib 2.0.0解决方案
让我们考虑下面的例子
它由以下代码生成:
次要的ticklabel确实消失了,通常显示它们的方法(如
plt.tick_params(axis='x', which='minor')
)失败了。第一步是在轴上显示10的所有幂,
然后,我们可以添加次要的ticklabels,
请注意,我限制了每十年包含4个小刻度(使用8也是可能的,但在这个例子中会使轴过度拥挤)。还要注意-这可能是这里的关键-
subs
参数,它给出了放置刻度的基数的整数幂的倍数(参见文档),给出了一个二十年的列表,而不是一个。最后,我们需要为次要tick使用
NullFormatter()
,以便不为它们显示任何ticklabel。fbcarpbf2#
从Matplotlib 3.5.2开始:
subs="auto"
将显示次要刻度线subs
。使用
subs="auto"
手动设置subs
jhdbpxl93#
这里的答案忽略了一个方便的事实,即对数缩放轴已经有了必要的定位器。至少从Matplotlib 3.6开始,使用
set_params()
的值强制小刻度就足够了:fzwojiic4#
带有空标签的主刻度将生成刻度,但不生成标签。
ljo96ir55#
将
matplotlib >= 2.0.2
的importanceofbeingernest中的excellent answer Package 成一个函数:这个函数可以被称为
或多个明确