【问题标题】:How to force Altair to order heatmap(rect) on a specific axis?如何强制 Altair 在特定轴上订购热图(矩形)?
【发布时间】:2019-04-29 16:09:47
【问题描述】:

我正在尝试在 Altair 中创建集群热图。创建热图效果很好,但我无法根据另一列的值对行重新排序。

这是我使用 seaborn 创建热图的代码 sn-p:

import pandas as pd
import numpy as np
import seaborn as sns
import altair as alt
import random

iris = sns.load_dataset("iris")
species = iris.pop("species")

# Clustermap for rows only
g = sns.clustermap(iris, col_cluster=False, cmap="magma")

# Get the reodered indices
reordered_indices = g.dendrogram_row.reordered_ind

# Create a dictionary to add this information to the longform dataframe later
reordering_dict = pd.Series(reordered_indices, index=iris.index.values).to_dict()

# Converting iris to tidyform
iris.reset_index(level=0, inplace=True)
iris_tidy = pd.melt(iris, id_vars=["index"], var_name="Paramaeter", value_name="value")

# Adding the ordering information
iris_tidy['order'] = iris_tidy['index'].map(reordering_dict)

这将导致:

现在使用 Altair 进行同样的尝试:

# Plotting using Altair
alt.Chart(iris_tidy, width=500, height=500).mark_rect().encode(
    alt.X("Paramaeter:N", bin=False, sort=None),
    alt.Y("order:O", bin=False),
    alt.Color("value:Q", scale=alt.Scale(scheme="magma")),
    order=alt.Order("order:Q", sort="ascending"),
).configure_scale(bandPaddingInner=0).configure_view(strokeOpacity=0, stroke="transparent").configure_axisY(
    labels=False, ticks=False
).configure_axisX(
    labelAngle=0, ticks=False
)

给了我这个:

我认为我错误地使用了alt.order()。我假设这样做的一种方法是使用序数列 order 本身来定义 Y 轴 - 但我将放弃与 index 关联的标签。

【问题讨论】:

  • 如果您的 order 列反映了值在 Seaborn 中显示的顺序,那么设置 y='order:O' 将使颜色以正确的顺序排列。它没有,这让我认为订单列没有正确指定。在担心轴标签之前,我会先努力做到这一点。

标签: python vega vega-lite altair


【解决方案1】:

如果要控制Y轴类别的排序顺序,可以使用y编码的sort属性。例如:

# Plotting using Altair
alt.Chart(iris_tidy, width=500, height=500).mark_rect().encode(
    alt.X("Paramaeter:N", bin=False, sort=None),
    alt.Y("index:O", sort=alt.EncodingSortField(field='order', order='ascending')),
    alt.Color("value:Q", scale=alt.Scale(scheme="magma")),
).configure_scale(bandPaddingInner=0).configure_view(strokeOpacity=0, stroke="transparent")

这与 seaborn 输出不匹配,但我认为这是因为计算出的 order 列没有反映 seaborn 图表中数据的顺序。

【讨论】:

  • 感谢您的回复。如果我重新排列数据框并使用 matplotlib imshow 绘制它,我仍然会得到与 Seaborn 完全相同的图(我相信这可以验证订单本身不是问题)-i.imgur.com/am0yiIy.png(对于纵横比感到抱歉)
  • 我在其他数据集上尝试了sort,它运行良好。在这种情况下,也许是由于 seaborn/imshow 中的插值导致结果看起来不同?
猜你喜欢
  • 2021-10-25
  • 2022-01-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多