【问题标题】:making square axes plot with log2 scales in matplotlib在 matplotlib 中使用 log2 比例制作方轴图
【发布时间】:2012-02-11 20:08:02
【问题描述】:

我想用 matplotlib 制作一个方轴散点图。通常使用set_scale("log") 效果很好,但它限制我使用log10。我想在 log2 中制作情节。我在这里看到了解决方案:How to produce an exponentially scaled axis?

但是如果你的数组中有 0 个值,它就非常复杂并且不起作用,我就是这样做的。我想像其他 numpy 函数一样忽略那些。

例如:

log2scatter(data1, data2)

其中 data1 和 data2 包含 0 在 x 和 y 轴上应具有对数刻度,并带有对数间隔刻度。和log10一样,除了log2...

谢谢。

【问题讨论】:

  • 日志只为正参数定义。这与基数无关,即它适用于自然对数、对数基数 10、对数基数 2 等。因此,除非你对这些零值做一些事情,否则你不能绘制在对数刻度中为零的东西。
  • 使用该问题的答案,但首先过滤掉 0 的 y 值及其对应的 x 值(这就是 numpy 无论如何都会忽略它们的方式)。
  • 在 numpy 中有什么优雅的方式来做到这一点?过滤使代码复杂化,因为现在我必须有一个未过滤的数组副本,以及一个过滤后的副本......

标签: python numpy scipy matplotlib


【解决方案1】:

只需指定basex=2basey=2

import matplotlib.pyplot as plt

fig, ax = plt.subplots()
ax.set_xscale('log', basex=2)
ax.set_yscale('log', basey=2)

ax.plot(range(1024))
plt.show()

对于过零行为,您指的是“对称对数”图(又名“symlog”)。不管它值多少钱,数据都不会被过滤掉,它只是一个接近 0 的线性图和其他任何地方的对数图。改变的是规模,而不是数据。

通常你只需要ax.set_xscale('symlog', basex=2),但目前对于符号图使用非 10 基数似乎有问题。

编辑: 呵!该错误似乎是由于一个经典错误:使用可变的默认参数。
我已经提交了一个错误报告,但如果你想修复它,你需要在 SymmetricalLogLocator__init__ 方法中对 lib/matplotlib/ticker.py 进行小修改,在第 1376 行附近。

代替

def __init__(self, transform, subs=[1.0]):
    self._transform = transform
    self._subs = subs
    ...

将其更改为类似于:

def __init__(self, transform, subs=None):
    self._transform = transform
    if subs is None:
        self._subs = [1.0]
    else:
        self._subs = subs
    ....

进行该更改后,它的行为符合预期...

import matplotlib.pyplot as plt
import numpy as np

fig, ax = plt.subplots()
ax.set_xscale('symlog', basex=2)
ax.set_yscale('symlog', basey=2)

x = np.arange(-1024, 1024)
ax.plot(x, x)

plt.show()

【讨论】:

  • 我使用 base=2 得到了非常奇怪的默认 x 和 y 限制(实际上即使没有它)。它不会将其设置为任一维度中的最小值。它选择了隐藏大部分数据的非常奇怪的限制。除了手动设置 x/y 限制之外,如何解决这个问题?
  • 不应该重写/破解 matplotlib 中的一个类来在 log2 和 log2 中制作一个怪异的散点图......这太可悲和令人沮丧。 :(
  • 符号日志部分是一个错误。您所指的限制只是对数图的限制行为方式。他们“捕捉”到最近的基地力量。如果您希望限制严格以数据的最小值和最大值结束,请指定ax.axis('tight')
  • matplotlib >= 3.3 中使用base=2 而不是basex=2basey=2
【解决方案2】:

如果你使用plt.xscale,你仍然需要指定basex,而不是base

plt.figure()
plt.plot(x, y)
plt.xscale('log', basex=2)
plt.show()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-03-26
    • 1970-01-01
    • 1970-01-01
    • 2012-07-19
    • 2019-05-09
    • 2021-09-10
    • 2015-01-20
    相关资源
    最近更新 更多