python - 如何在matplotlib中将刻度设置为2的幂?
问题描述
我想绘制一个 xtick 值以 2 次方增长的图形。
例如,
import pandas as pd
data = pd.DataFrame({
'x': [2, 4, 8, 16, 32, 64],
'y': [1, 2, 3, 4, 5, 6]
})
对于像上面示例这样整齐的数据,我可以x2
在这个数据框中创建一个 1~6 的辅助列,然后将图形的 xticklabels 设置为 2^1~2^6。但是,此解决方法不适用于具有其他值(如 3、7 或 30)的情况。
似乎 matplotlib 只支持对数刻度。如何以 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'
在右下角显示 a)。让我知道是否有更通用的解决方案。
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()
推荐阅读
- python - XGBoost 网格搜索评分='roc_auc' 和 roc_auc_score 的不同 roc_auc?
- powershell - Docker microsoft/nanoserver 无法启动
- javascript - 如果页面内容的高度小于页面高度,则不会触发 ioninfinite 事件
- bash - Bash 管道分隔字符串到命令的参数中
- office365 - 为什么我看不到“创建传出 webhook”链接?
- c++ - 如何通过Windows中的命名管道将消息传递给子进程
- javascript - 编辑输入类型时如何更改值属性?
- java - 将原始数组转换为盒装数组时如何减少强制转换次数
- javascript - 在 youtube 页面中放置两个不同的滚动条以改善自定义 UI 体验
- firebase - RN / Firebase:将电话凭据与现有帐户相关联