【问题标题】:Overlapping axis tick labels in logarithmic plots对数图中重叠的轴刻度标签
【发布时间】:2017-10-01 05:22:43
【问题描述】:

我有一些代码在一年前使用 pyplot 运行良好;我使用plt.plot(x,y) 使用对数 y 轴制作了一个绘图,并用自定义集替换了 y 轴刻度和刻度标签,如下所示:

# set the axis limits
Tmin = -100  # min temperature to plot
Tmax = 40    # max temperature
Pmin = 100   # min pressure
Pmax = 1000  # max pressure
plt.axis([Tmin, Tmax, Pmax, Pmin])

# make the vertical axis a log-axis
plt.semilogy()

# make a custom list of tick values and labels
plist = range(Pmin,Pmax,100)
plabels = []
for p in plist:
    plabels.append(str(p))

plt.yticks(plist,plabels)

在最近将我的 python 安装更新到当前版本的 miniconda 之后,我现在发现虽然新标签仍然出现,但它们被 matplotlib 的科学计数法默认标签部分覆盖。所以看起来,虽然上面的代码用于替换默认刻度和标签,但现在它只是添加到它们。

我必须做什么才能重新获得所需的行为?为什么它首先发生了变化?

【问题讨论】:

  • 可能是一个错误。它只发生在比例不是线性的时候。
  • 如果是错误,是否有解决方法?另外,在哪里报告可能的错误?
  • 试试github page

标签: python matplotlib


【解决方案1】:

您遇到的问题是a known bug,即not easy to fix。问题的核心是主要和次要滴答声的混合;设置yticks 会重新定义主要刻度,而次要刻度会导致重叠。

解决问题之前的解决方法是使用 plt.minorticks_off()(或使用面向对象的 API 的 ax.minorticks_off())手动禁用次要刻度:

Tmin = -100  # min temperature to plot
Tmax = 40    # max temperature
Pmin = 100   # min pressure
Pmax = 1000  # max pressure
plt.axis([Tmin, Tmax, Pmax, Pmin])

# make the vertical axis a log-axis
plt.semilogy()
plt.minorticks_off() # <-- single addition

# make a custom list of tick values and labels
plist = range(Pmin,Pmax,100)
plabels = []
for p in plist:
    plabels.append(str(p))

plt.yticks(plist,plabels)

至于 何时 发生变化:它came with the default style changes 是用 matplotlib 2.0 制作的。

【讨论】:

    【解决方案2】:

    也许值得一提的是,标记轴的方式通常是自动执行的。根据要显示的值范围,应用不同的设置,matplotlib style change 到 2.0 版状态

    现在,当轴视图限制跨越的范围小于或等于两个主要刻度之间的间隔时,日志轴上的次要刻度会被标记。

    从这个意义上说,报告的行为并不是真正的错误;这是需要的。

    在更改默认轴标签时,可能仍会使用自动标签。刻度和标签是使用matplotlib.ticker 的定位器和格式化程序创建的。可以获得所需的情节,例如如下,其中MultipleLocator 设置每 100 个单位的滴答声,而次要滴答声设置为NullLocator。要将刻度格式化为标量值而不是科学格式,可以使用 ScalarFormatter

    from matplotlib import pyplot as plt
    import matplotlib.ticker
    
    plt.axis([-100, 40, 100, 1000])
    
    plt.semilogy()
    
    plt.gca().yaxis.set_major_locator(matplotlib.ticker.MultipleLocator(100))
    plt.gca().yaxis.set_minor_locator(matplotlib.ticker.NullLocator())
    plt.gca().yaxis.set_major_formatter(matplotlib.ticker.ScalarFormatter())
    
    plt.plot([-100, 40], [100, 1000])
    plt.show()
    

    总的来说,这个解决方案比通过.yticks 手动设置刻度更通用。

    【讨论】: