python - 在 seaborn 热图上编辑轴刻度的标签和位置会导致绘图为空
问题描述
我正在尝试在两个轴上绘制带有自定义位置和标签的 seaborn 热图。数据框如下所示:
我可以正常绘制这个seaborn.heatmap
:
fig, ax = plt.subplots(figsize=(8, 8))
sns.heatmap(genome_freq.applymap(lambda x: np.log10(x+1)),
ax=ax)
plt.show()
我有一个我想设置为 xticks ( binned_chrom_genome_pos
) 的位置列表:
[1000000, 248000000, 491000000, 690000000, 881000000, 1062000000, 1233000000, 1392000000, 1538000000, 1679000000, 1814000000, 1948000000, 2081000000, 2195000000, 2301000000, 2402000000, 2490000000, 2569000000, 2645000000, 2709000000, 2772000000, 2819000000, 2868000000, 3023000000]
但是,当我尝试修改 xticks 时,绘图变为空:
plt.xticks(binned_chrom_genome_pos)
我还注意到 x 轴标签与指定的刻度不对应。
有人可以帮助我正确地绘制这个吗?
解决方案
为什么代码做它做的事
ax.get_xticks()
返回刻度的位置。您可以看到它们介于 0.5 和 3000 之间。这些值是指数据的索引。plt.xticks
由或设置的大值ax.set_xticks
仍被解释为数据索引。因此,如果您有 10 行数据,并且设置xticks
为[0, 1000]
,则图中的数据将仅占 x 范围的 1%,因此会消失。我不确定我是否清楚,所以我将举一个合成数据的例子:
import seaborn as sns
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
#generating data
dic = {a:np.random.randint(0,1000,100) for a in range(0,1000000, 10000)}
genome_freq = pd.DataFrame(dic, index=range(0,1000000, 10000))
#plotting heatmaps
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(8, 4))
sns.heatmap(genome_freq.applymap(lambda x: np.log10(x+1)),
ax=ax1)
sns.heatmap(genome_freq.applymap(lambda x: np.log10(x+1)),
ax=ax2)
old_ticks = ax2.get_xticks()
print(np.min(old_ticks), np.max(old_ticks), len(old_ticks)) # prints 0.5 99.5 34
ax2.set_xticks([0,300]) # setting xticks with values way larger than your index squishes your data
plt.show()
可以做些什么来解决它
因此,您要做的是根据数据的大小更改 xticks,然后覆盖xticklabels
:
鉴于您的问题中的新标签:
new_labels = [1000000, 248000000, 491000000, 690000000, 881000000, 1062000000, 1233000000, 1392000000, 1538000000, 1679000000, 1814000000, 1948000000, 2081000000, 2195000000, 2301000000, 2402000000, 2490000000, 2569000000, 2645000000, 2709000000, 2772000000, 2819000000, 2868000000, 3023000000]
len(new_labels) # returns 24
fig, ax = plt.subplots(figsize=(4, 4))
sns.heatmap(genome_freq.applymap(lambda x: np.log10(x+1)),
ax=ax)
所以,现在我们想要在前一个最小值和前一个最大值之间有 24 个均匀间隔的 xticks。我们可以使用np.linspace
来实现:
old_ticks = ax.get_xticks()
new_ticks = np.linspace(np.min(old_ticks), np.max(old_ticks), len(new_labels))
ax.set_xticks(new_ticks)
ax.set_xticklabels(new_labels)
plt.show()
推荐阅读
- sql - 需要帮助以根据时间戳从 oracle DB 中获取行
- java - PowerShell 和 Jar 执行
- stata - 循环遍历许多没有规则的名称
- r - 在ggplot2中绘制图例
- javascript - 简单的 Javascript 代码在 Windows Vista 中不起作用
- mysql - MySQL 上的 Django QuerySet 过滤器无法正确显示
- c++ - 加减法十六进制计算器
- macos - 如何在 Xamarin.Forms MacOs 中更改 ActivityIndicator 的颜色?
- javascript - 使用此 .charAt() 的任何替代方式?
- php - PHP file_exists 方法未按预期工作