在matplotlib中绘制对数2刻度的平方坐标轴图

37 投票
2 回答
62909 浏览
提问于 2025-04-17 10:23

我想用matplotlib画一个正方形的散点图。通常使用 set_scale("log") 是很有效的,但这样只能用log10。我想用log2来画这个图。我在这里看到了解决方案:如何生成指数缩放的坐标轴?

不过这个方法有点复杂,而且如果你的数据里有0值的话就不适用了,而我的数据里确实有0。我希望能像其他numpy函数那样简单地忽略这些0值。

举个例子:

log2scatter(data1, data2)

在data1和data2中包含0的情况下,x轴和y轴应该有对数刻度,并且刻度间隔是对数间隔的。就像log10那样,只不过是log2...

2 个回答

16

如果你在使用 plt.xscale 的时候,记得要用 basex 来设置基数,而不是用 base

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

Matplotlib 版本 >= 3.3:

设置 base=2:

import matplotlib.pyplot as plt

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

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

Matplotlib 版本 < 3.3:

设置 basex=2 和/或 basey=2 来调整 x 轴和 y 轴。

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) 就可以了,但目前在 symlog 图中使用非 10 的基数似乎有点问题。

编辑: 哈哈!这个问题看起来是一个经典错误:使用了可变的默认参数。
我已经提交了一个错误报告,但如果你想自己修复,需要对 lib/matplotlib/ticker.py 文件进行小改动,大约在第 1376 行,SymmetricalLogLocator__init__ 方法里。

把这段代码

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()

在这里输入图片描述

撰写回答