【问题标题】:Better ticks and tick labels with log scale更好的刻度和刻度标签与对数刻度
【发布时间】:2017-09-22 17:33:44
【问题描述】:

我正在努力获得更好看的对数图,除了一个小问题,我几乎得到了我想要的。

我的示例偏离标准设置的原因是 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轴有两个问题:

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

  2. 右下角可怕的“偏移”

读了很多,我加了三行代码:

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. 我想要一些介于 1 和 2 之间的额外刻度
  2. 1 处的标签格式错误。它应该是“1.0”

所以我在格式化语句之前插入了以下行:

ax.xaxis.set_major_locator(mpl.ticker.MultipleLocator(0.2))

我终于得到了我想要的滴答声:

我现在有 8 个主要刻度和 2 个次要刻度。现在,这看起来几乎是正确的,只是 0.6、0.8 和 2.0 处的刻度标签看起来比其他的更粗。这是什么原因,我该如何纠正?

【问题讨论】:

  • 这可能是一个渲染工件。对我来说,如果我以更高分辨率 (fig.savefig("test.png",dpi=300)) 保存图形,它就会消失。如果我删除 set_minor_formatter 行,它也会消失,但是你会在 0.7 和 0.9 处丢失次要刻度。
  • 0.6 和 0.8 更粗,因为它们被写为次要刻度标签和主要刻度标签;当它渲染它们时,它们必须彼此稍微偏移,因此它们看起来更粗。
  • @tom 它们没有偏移,这是由于两个完全重叠的文本的抗锯齿。
  • @ImportanceOfBeingErnest:很好,我从来没有意识到这就是原因。那么当文本被抗锯齿时,部分填充的像素是半透明的吗?因此,当您有两个重叠的文本时,那些半透明的像素会变暗吗?
  • @tom 虽然抗锯齿可能不适用于透明度本身,但这是人们最能想象发生的事情的方式。另一方面,如果您将两个不同颜色的文本(甚至线条)放在彼此的顶部,您会看到一些其他效果,因此用于抗锯齿的不仅仅是颜色混合。现在可能这有点离题了。

标签: matplotlib


【解决方案1】:

一些标签显示为粗体的原因是它们是主要和次要刻度标签的一部分。如果两个文本完全重叠,由于抗锯齿,它们会显得更粗。
您可以决定只使用次要刻度标签,并使用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()

对于更通用的标签,当然可以将定位器子类化,但我们需要知道用于确定刻度标签的逻辑。 (由于我没有从问题中看到所需刻度的明确定义的逻辑,我觉得现在提供这样的解决方案会浪费精力。)

【讨论】:

  • @IOBE,明确指定刻度正是我不想做的事情。但是,您建议只使用一种刻度是一个很好的建议。我决定只使用主要刻度,现在插入这一行给了我很好看的刻度:ax.xaxis.set_minor_locator(mpl.ticker.NullLocator())(也可以删除 set_minor_formatter 行)。
  • 不清楚你的意思。如何在不明确设置的情况下获得刻度标签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 为我自动缩放轴,我喜欢这样。
  • 我不明白这如何解决问题;但如果你对此感到满意,为什么不呢。
猜你喜欢
  • 2014-03-22
  • 2021-06-14
  • 1970-01-01
  • 1970-01-01
  • 2022-06-16
  • 2011-11-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多