Matplotlib 更好的刻度和带有对数刻度的刻度标签

Matplotlib 更好的刻度和带有对数刻度的刻度标签,matplotlib,Matplotlib,我试图得到更好的日志图,我几乎得到了我想要的,除了一个小问题 我的例子抛弃了标准设置的原因是x值被限制在不到十年的范围内,我想使用十进制,而不是科学记数法 请允许我举例说明: import matplotlib.pyplot as plt %matplotlib inline import matplotlib as mpl import numpy as np x = np.array([0.6,0.83,1.1,1.8,2]) y = np.array([1e-5,1e-4,1e-3,1e

我试图得到更好的日志图,我几乎得到了我想要的,除了一个小问题

我的例子抛弃了标准设置的原因是x值被限制在不到十年的范围内,我想使用十进制,而不是科学记数法

请允许我举例说明:

import matplotlib.pyplot as plt
%matplotlib inline
import matplotlib as mpl
import numpy as np

x = np.array([0.6,0.83,1.1,1.8,2])
y = np.array([1e-5,1e-4,1e-3,1e-2,0.1])

fig1,ax = plt.subplots()
ax.plot(x,y)
ax.set_xscale('log')
ax.set_yscale('log')
产生:

x轴有两个问题:

  • 使用科学记数法,在这种情况下会适得其反

  • 右下角可怕的“偏移”

  • 经过大量阅读,我添加了三行代码:

    ax.xaxis.set_major_formatter(mpl.ticker.ScalarFormatter())
    ax.xaxis.set_minor_formatter(mpl.ticker.ScalarFormatter())
    ax.ticklabel_format(style='plain',axis='x',useOffset=False)
    
    这将产生:

    我的理解是,有5个小刻度和1个大刻度。它要好得多,但仍然不完美:

  • 我想要一些介于1和2之间的额外刻度
  • 1处标签的格式错误。它应该是“1.0”
  • 因此,我在formatter语句之前插入了以下行:

    ax.xaxis.set_major_locator(mpl.ticker.MultipleLocator(0.2))
    
    我终于得到了我想要的滴答声:


    我现在有8个大刻度和2个小刻度。现在,这看起来几乎是正确的,除了0.6、0.8和2.0的记号标签比其他标签更粗体。出现这种情况的原因是什么?我如何更正它?

    原因是,一些标签显示为粗体,因为它们是主标签和次标签的一部分。如果两个文本完全重叠,则由于消除混叠,它们看起来更粗体。
    您可以决定只使用次要标签,并使用
    NullLocator
    设置主要标签

    由于您希望标签的位置确实是特定的,因此没有自动定位器可以提供开箱即用的标签。对于这种特殊情况,最简单的方法是使用
    FixedLocator
    ,并将您想要的标签指定为列表

    import matplotlib.pyplot as plt
    import matplotlib.ticker as ticker
    import numpy as np
    
    x = np.array([0.6,0.83,1.1,1.8,2])
    y = np.array([1e-5,1e-4,1e-3,1e-2,0.1])
    
    fig1,ax = plt.subplots(dpi=72, figsize=(6,4))
    ax.plot(x,y)
    ax.set_xscale('log')
    ax.set_yscale('log')
    
    locs = np.append( np.arange(0.1,1,0.1),np.arange(1,10,0.2))
    ax.xaxis.set_minor_locator(ticker.FixedLocator(locs))
    ax.xaxis.set_major_locator(ticker.NullLocator())
    
    ax.xaxis.set_minor_formatter(ticker.ScalarFormatter())
    
    plt.show()
    


    对于更通用的标签,当然可以对定位器进行子类化,但是我们需要知道用于确定标签的逻辑。(由于我看不到问题中所需记号的定义良好的逻辑,我觉得现在提供这样的解决方案是白费力气的。)

    这可能是渲染工件。对我来说,如果我以更高的分辨率保存图形(
    fig.savefig(“test.png”,dpi=300)
    ),它就会消失。如果我删除
    set_minor_formatter
    行,它也会消失,但是您会丢失0.7和0.9处的次刻度。0.6和0.8处的次刻度更粗体,因为它们同时作为次刻度标签和主刻度标签写入;当它渲染它们时,它们必须彼此稍微偏移,因此它们看起来更粗体。@tom它们没有偏移,这是由于两个完全重叠的文本的抗锯齿。@ImportanceOfBeingErnest:说得好,我从未意识到这就是原因。因此,当文本被抗锯齿时,部分填充的像素是半透明的吗?因此,当你有两个重叠的文本时,那些半透明的像素会变得更暗?@tom尽管抗锯齿可能无法与透明度一起工作,但这是人们最能想象发生了什么的方式。另一方面,如果您将两个不同颜色的文本(甚至行)放在彼此的顶部,您会看到一些其他效果,因此用于抗锯齿的不仅仅是颜色混合。这可能有点离题了。@IOBE,显式指定记号正是我不想做的。然而,你建议只使用一种蜱虫是一个很好的建议。我决定只使用主刻度,插入这一行现在给了我非常好看的刻度:
    ax.xaxis.set_minor_locator(mpl.ticker.NullLocator())
    (set_minor_格式化程序行也可以删除)。不清楚您的意思。如何在不进行明确设置的情况下获得ticklebels
    0.6,0.7,0.8,0.9,1.0,1.2,1.4,1.6,1.8,2.0
    ?让我澄清一下:我得到的刻度只是0.2的主要刻度倍数。因此在0.7或0.9处没有滴答声。matplotlib为我自动缩放轴,我喜欢这样。我不知道这如何解决这个问题;但是如果你对它满意,为什么不呢。