python - 彩条上的手动刻度
问题描述
我正在尝试创建一个对数颜色条。我知道之前有人问过这个问题,比如这里或这里,但是在答案中,绘图函数用于创建对数颜色条。我想独立于绘图功能。所以我写了一个函数来计算刻度的位置并相应地创建标签,但是当我尝试更新颜色条上的刻度和标签时它不起作用:
所以假设我有以下情节。
现在我的轴看起来像这样:
list(cbar.ax.get_yticklabels())
>>> [Text(1, 0.0, '$\\mathdefault{10^{0}}$'),
Text(1, 0.5, ''),
Text(1, 1.0, ''),
Text(1, 1.5, ''),
Text(1, 2.0, ''),
Text(1, 2.5, ''),
Text(1, 3.0, ''),
Text(1, 3.5, '')]
使用我的函数后,我得到了刻度的位置(每个自然数都有一个标签,其他的没有,因为它们像次要刻度一样使用):
pos = [0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0, 2.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7, 2.8, 2.9, 3.0, 3.1, 3.2, 3.3, 3.4, 3.5]
和我的标签:
labels = ['$\\mathdefault{10^{3}}$', '', '', '', '', '', '', '', '', '', '$\\mathdefault{10^{3}}$', '', '', '', '', '', '', '', '', '', '$\\mathdefault{10^{3}}$', '', '', '', '', '', '', '', '', '', '$\\mathdefault{10^{3}}$', '', '', '', '', '']
当我尝试更改刻度和标签时:
cbar.set_ticks(pos)
cbar.set_ticklabels(labels)
我明白了:
[Text(1, 0.0, '$\\mathdefault{10^{0}}$'), Text(1, 0.5, ''), Text(1, 1.0, ''), Text(1, 1.5, ''), Text(1, .0, ''), Text(1, 2.5, ''), Text(1, 3.0, ''), Text(1, 3.5, ''), Text(1, 0, ''), Text(1, 0, ''), Text(1, 0, ''), Text(1, 0, ''), Text(1, 0, ''), Text(1, 0, ''), Text(1, 0, ''), Text(1, 0, ''), Text(1, 0, ''), Text(1, 0, ''), Text(1, 0, ''), Text(1, 0, ''), Text(1, 0, ''), Text(1, 0, ''), Text(1, 0, ''), Text(1, 0, ''), Text(1, 0, ''), Text(1, 0, ''), Text(1, 0, ''), Text(1, 0, ''), Text(1, 0, ''), Text(1, 0, ''), Text(1, 0, ''), Text(1, 0, ''), Text(1, 0, ''), Text(1, 0, ''), Text(1, 0, ''), Text(1, 0, '')]
所以添加了额外的位置,但都在位置 0 并且没有标签。
使用
cbar.ax.set_yticks(pos)
cbar.ax.set_yticklabels(labels)
也不起作用,而是:
[Text(1, 0.0, '$\\mathdefault{10^{3}}$'), Text(1, 0.5, ''), Text(1, 1.0, ''), Text(1, 1.5, ''), Text(1, .0, ''), Text(1, 2.5, ''), Text(1, 3.0, ''), Text(1, 3.5, ''), Text(1, 0, ''), Text(1, 0, ''), Text(1, 0, '$\\mathdefault{10^{3}}$'), Text(1, 0, ''), Text(1, 0, ''), Text(1, 0, ''), Text(1, 0, ''), Text(1, 0, ''), Text(1, 0, ''), Text(1, 0, ''), Text(1, 0, ''), Text(1, 0, ''), Text(1, 0, '$\\mathdefault{10^{3}}$'), Text(1, 0, ''), Text(1, 0, ''), Text(1, 0, ''), Text(1, 0, ''), Text(1, 0, ''), Text(1, 0, ''), Text(1, 0, ''), Text(1, 0, ''), Text(1, 0, ''), Text(1, 0, '$\\mathdefault{10^{3}}$'), Text(1, 0, ''), Text(1, 0, ''), Text(1, 0, ''), Text(1, 0, ''), Text(1, 0, '')]
所以我想知道在尝试更改刻度/标签时我做错了什么。非常感谢任何帮助。
如果我在这里感兴趣的是我用来创建颜色条和创建新刻度和标签的函数:
import matplotlib as mpl
import numpy as np
def make_log_ticks(current_ticks):
min_ = np.inf
max_ = -np.inf
for elem in current_ticks:
pos, val = elem.get_position()
if val < min_:
min_ = val
if val > max_:
max_ = val
#new_ticks = []
new_labels = []
new_pos = []
for i in range(int(min_*10), int(max_*10+1)):
if i%10 == 0:
new_pos.append(i/10)
new_labels.append("$\\mathdefault{10^{"+str(int(val))+"}}$")
#new_ticks.append(mpl.text.Text(1, i/10, "$\\mathdefault{10^{int(val)}}$"))
else:
new_pos.append(i/10)
new_labels.append('')
#new_ticks.append(mpl.text.Text(1, i/10, ""))
#return new_ticks, new_pos, new_labels
return new_pos, new_labels
def make_cbar(data, cmap=mpl.cm.jet, log=False):
m = mpl.cm.ScalarMappable(cmap=cmap)
if log:
m.set_array(np.log10(list(set(data))))
norm = plt.Normalize(np.log10(min(data)), np.log10(max(data)))
else:
m.set_array(list(set(data)))
norm = plt.Normalize(min(data), max(data))
cbar = plt.colorbar(m)
cbar.ax.tick_params(axis='both', which='major', width=3 , length=5)
cbar.ax.tick_params(axis='both', which='minor', width=2 , length=3)
if log:
pos, labels = make_log_ticks(list(cbar.ax.get_yticklabels()))
cbar.ax.set_yticks(pos)
cbar.ax.set_yticklabels(labels)
return cbar, lambda c: m.cmap(norm(np.log10(c)))
else:
return cbar, lambda c: m.cmap(norm(c))
解决方案
我不知道如何告诉颜色条是对数的。但是我发现了如何做到这一点,以防有人偶然发现类似的问题:
m = mpl.cm.ScalarMappable(cmap=cmap, norm=mpl.colors.LogNorm())
norm = mpl.colors.LogNorm(min(data), max(data))
m.set_array(list(set(data)))
cbar = plt.colorbar(m)
可以将 Mappable 设置为使用对数范数。然后标签将自动完成。那就不用手动了。但是,我无法更改标签的问题仍然存在。
推荐阅读
- android - 排球错误:意外的响应代码 400
- android - 迁移到视图绑定后按钮的颜色不适用
- python - 将希腊句子括在标签之间或查找并替换包含希腊字符的句子部分
- android - 找不到 ```org.jetbrains.kotlin:kotlixn-stdlib:1.4.10 ```并且找不到 ```android.arch.lifecycle:common-java8:2.2.0。```
- python-3.x - 如何在python中连接字符串
- slurm - 将 Slurms Fairshare 因子应用于新数据库
- python - torch.manual_seed 是否包含 torch.cuda.manual_seed_all 的操作?
- c++ - 如何防止基于编译时详细级别编译日志记录字符串?
- docker - 看来您正在容器内运行 Vue CLI
- java - 将 API Gateway 自定义域从 Edge 切换到区域并将 TLS 从 1.0 切换到 1.2 后“连接重置”