如何在matplotlib中将刻度设置为2的幂?

4
我可以帮您翻译以下内容,涉及IT技术,内容如下:

我想绘制一个x轴刻度值按2的幂增长的图形。

例如:

import pandas as pd
data = pd.DataFrame({
    'x': [2, 4, 8, 16, 32, 64],
    'y': [1, 2, 3, 4, 5, 6]
})

我期望的是像这样的图形: enter image description here 对于像上面样例中整洁的数据,我可以在数据框中创建一个辅助列x2,用1~6填充,然后将图形的xticklabels设置为2^1~2^6。但是,这种解决方法不适用于其他值如3、7或30的情况。
看起来matplotlib只支持对数刻度。那么我如何实现2的幂次刻度的刻度线?

你提到的“3、7或30等其他数值”,是指x值的数量,而不是所需的功率尺度,对吗? - Benjamin Loison
看起来和这个问题重复了。 - Benjamin Loison
1个回答

2
这是一个特别棘手的问题(我没想到会是这样的^^)。
好的,让我们从一些阅读提示开始:你想设置x/y轴的比例尺:.matplotlib.axes.Axes.set_yscale()。虽然有几种标准的比例尺(默认值显然是'liner'),但你可以设置自定义的比例尺。这里有一些不错的示例。
基本上,你需要定义两个函数,一个是正向转换,一个是逆向转换。 之后,你需要正确设置刻度(因为你在绘图之后应用了转换,刻度保持不变(但由于转换的原因位置可能不同)。对此有两种选择:
  • 通过手动设置刻度 matplotlib.axes.Axes.set_xticks(),或者
  • 通过设置轴的定位器matplotlib.axes.Axes.xaxis.set_major_locator()。如果您使用网格,建议使用此方法。但由于我的知识有限,我希望能得到更详细的解释(因为现在我也对这个功能很好奇^^)

现在来到棘手的部分:将刻度标签格式化为表示'2^x'。我没有找到比将它们明确设置为字符串更好的方法。似乎只能在受限范围内更改通用格式,参见matplotlib.pyplot.ticklabel_format(),其中可以选择是否以科学计数法显示(即在右下角显示'10^x')。如果有更通用的解决方案,请告诉我。

import pandas as pd
import numpy as np
from matplotlib import pyplot as plt
from matplotlib.ticker import FixedLocator

# create dummy data
df = pd.DataFrame({
    'x': [2**x for x in range(1,10)],
    'y': list(range(1,10))
})

def forward(x):
    return np.log2(x)


def inverse(x):
    return 2**x

# open figure
fig, ax = plt.subplots(2,2)
axs = ax.flatten()
for i in range(0,4):
    # plot data
    axs[i].plot(df['x'],df['y'])
    if i > 0:
        # set scale function
        axs[i].set_xscale('function', functions=(forward,inverse))
    if i > 1:
        # set ticks
        # - OPTION 1
        axs[i].set_xticks(df['x'])
        # - OPTION 2
      axs[i].xaxis.set_major_locator(FixedLocator(2**np.arange(1,10)))
    if i > 2:
        # est tick labels
        axs[i].set_xticklabels( [f"2^{j:.0f}" for j in np.log2(df['x'])] )

plt.show()

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接