python - 将非线性比例与 Seaborn 热图一起使用

标签 python seaborn

我正在尝试对下面的热图使用对数刻度。我需要一个用于 0-30 之间数字的热图,然后是另一个配色方案,用于更大的值,这可能是错误的。

尝试了几种不同的方法,但仍然很困惑。感谢您的帮助。

干杯!

这是我正在使用的当前脚本。

read_occupancy = pd.read_csv (r'C:\Users\holborm\Desktop\Visualisation\dataaxisplotstuff.csv')   #read the csv file (put 'r' before the path string to address any special characters, such as '\'). Don't forget to put the file name at the end of the path + ".csv"

df = DataFrame(read_occupancy)    # assign column names


#create time and detector name axis

sns.heatmap(df.set_index('Row Labels').T, cmap='magma', linecolor='white', linewidths=.05)
sns.clustermap(df.set_index('Row Labels').T, cmap='magma', linecolor='white', linewidths=.05)

根据问题/答案更新

import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
from matplotlib.colors import LogNorm
def mix_palette():
    palette = sns.color_palette("GnBu", 10)
    palette[9] = sns.color_palette("OrRd", 10)[9]
    return palette


def set_ax(iax):
    for text in iax.texts:
        if float(text.get_text()) < 30:
            text.set_text("")
    iax.figure.tight_layout()


def load_data(path):
    initial = pd.read_csv(path, delim_whitespace=True)
    columns = list(initial.columns.values)[1:]
    rows = []
    for values in initial.values:
        rng = values[0]
        for column, value in zip(columns, values[1:]):
            rows.append([rng, column, value])
    return pd.DataFrame(data=rows, columns=['range', 'label', 'quantity'])
data = load_data('dataaxisplotstuff.csv')
data = data.pivot("range", "label", "quantity")
mi, ma = data.values.min(), data.values.max()
ax = sns.heatmap(data, cmap=mix_palette(), annot=True, square=True, cbar_kws={'ticks': ticker.LogLocator(numticks=8)},
                 xticklabels=True, yticklabels=True, norm=LogNorm(vmin=mi, vmax=ma))
set_ax(ax)
plt.show()

收到这个错误

TypeError                                 Traceback (most recent call last)
<ipython-input-5-7466da1cd6c9> in <module>()
      1 data = load_data('dataaxisplotstuff.csv')
      2 data = data.pivot("range", "label", "quantity")
----> 3 mi, ma = data.values.min(), data.values.max()
      4 ax = sns.heatmap(data, cmap=mix_palette(), annot=True, square=True, cbar_kws={'ticks': ticker.LogLocator(numticks=8)},
      5                  xticklabels=True, yticklabels=True, norm=LogNorm(vmin=mi, vmax=ma))

~\AppData\Local\Continuum\anaconda3\lib\site-packages\numpy\core\_methods.py in _amin(a, axis, out, keepdims)
     27 
     28 def _amin(a, axis=None, out=None, keepdims=False):
---> 29     return umr_minimum(a, axis, None, out, keepdims)
     30 
     31 def _sum(a, axis=None, dtype=None, out=None, keepdims=False):

TypeError: '<=' not supported between instances of 'float' and 'str'

最佳答案

我试试看。根据我的理解,您需要一个热图,其中正常值的配色方案和离群值的颜色不同,而且热图必须采用对数刻度。为此,我将使用 pandasseabornmatplotlib。版本是 pandas:0.22.0,matplotlib:2.2.2 和 seaborn:0.9.0。首先是一些功能:

import matplotlib.pyplot as plt
import pandas as pd
import seaborn as sns
from matplotlib.colors import LogNorm


def mix_palette():
    palette = sns.color_palette("GnBu", 10)
    palette[9] = sns.color_palette("OrRd", 10)[9]
    return palette


def set_ax(iax):
    iax.collections[0].colorbar.set_ticklabels(['10', '30'])
    for text in iax.texts:
        if float(text.get_text()) < 30:
            text.set_text("")
    iax.figure.tight_layout()


def load_data(path):
    initial = pd.read_csv(path, delim_whitespace=True)
    columns = list(initial.columns.values)[1:]
    rows = []
    for values in initial.values:
        rng = values[0]
        for column, value in zip(columns, values[1:]):
            rows.append([rng, column, value])
    return pd.DataFrame(data=rows, columns=['range', 'label', 'quantity'])

mix_palette 函数创建混合调色板,set_ax 对图形进行一些调整,最后 load_data 接收指向 csv 的路径就像示例中的一样(使用空格作为分隔符)。 load_data 的输出是一个 DataFrame,其形状与来自 seaborn 数据集的航类相同,例如 (row_name, column_name, value)。现在绘图代码:

data = load_data('data.csv')
data = data.pivot("range", "label", "quantity")
mi, ma = data.values.min(), data.values.max()
ax = sns.heatmap(data, cmap=mix_palette(), annot=True, square=True, cbar_kws={'ticks': [10, 30],
                 xticklabels=True, yticklabels=True, norm=LogNorm(vmin=mi, vmax=ma))
set_ax(ax)
plt.savefig('image.png', bbox_inches='tight')
plt.show()

输出是: enter image description here 这会以红色绘制接近或高于 30 的值,并显示数值以实现更好的可视化目的。更详细:

  • mix_palette 从默认调色板 "GnBu""OrRd" 创建混合。
  • 第一行set_ax 将颜色条(侧面的条)的标签设置为10 和30,循环将那些低于30 的单元格的值设置为空字符串。最后使布局紧凑(轴值的标签很大,您可以这样做以显示所有标签)。
  • cmap 参数接收调色板,annot=True 显示单元格的值,square=True 制作热图的单元格square, 'ticks': [10, 30] 设置颜色条一侧刻度的位置和 norm=LogNorm(vmin=mi, vmax=ma)是处理对数刻度的那个。
  • 要保存绘图,您可以使用该功能 plt.savefig('image.png', bbox_inches='tight') 确保在显示图像之前使用它。

关于python - 将非线性比例与 Seaborn 热图一起使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51816297/

相关文章:

python - Python 中的时间范围重叠算法

python - 如何合并两个具有相同元素的字典(键 :val)

python - seaborn 条形图上的黑线是什么意思?

python - 条形图,带有单独的正值和负值条形图

python - 在热图中使颜色条值整数 matplotlib seaborn

python - 从 Linux 上的 Web 服务器在 Windows 上运行任务的最佳方式

python - StringListProperty 限制为 500 个字符字符串(Google App Engine/Python)

python - 在 TensorFlow 中导入巨大的非图像数据集

python - 如何对热图的索引 DataFrame 上的 x 轴和 y 轴执行自定义排序?

python - 如何使 seaborn.heatmap 变大(正常大小)?