为什么 Altair 在使用对数刻度时返回空图表?

Why is Altair returning an empty chart when using log scale?

在 JupyterLab 中,我使用 altair python 库创建了一个条形图,其中 x 轴是对数刻度,但它只返回一个空图表。

绘制常规条形图可以正常工作,不同比例类型也可以。

我查看了 https://altair-viz.github.io/user_guide/troubleshooting.html#display-troubleshooting 上的故障排除文档,尝试了不同版本的 JupyterLab,并仔细检查了我的代码,但未能解决问题。

以下是我使用的版本:

Python 3.7.4(默认,2019 年 8 月 9 日,18:34:13)[MSC v.1915 64 位 (AMD64)] JupyterLab 1.1.3 牵牛星 3.2.0 Pandas 0.25.1

这是我的代码:

import altair as alt
import pandas as pd

df = pd.DataFrame(
[['L1', 2000],
 ['L2', 0],
 ['L3', 0],
 ['L4', 3000],
 ['L5', 101],
 ['L6', 100],
 ['L7', 99],
 ['L8', 250],
 ['L9', 770000]],
columns=['group', 'foos'])

chart = alt.Chart(df)

alt.Chart(df).mark_bar().encode(
    alt.X('foos', scale=alt.Scale(type='log')),
    y='group')

image of output

零的对数是负无穷大,显示有问题。渲染器会生成有关此的警告,您可以在渲染图表时在 javascript 错误日志中看到这些警告:

> WARN A log scale is used to encode bar's x. This can be misleading as the width of the bar can be arbitrary based on the scale domain. You may want to use point mark instead.
> WARN Log scale domain includes zero: [0,770000]

解决这个问题的一种方法是从图表中过滤掉非正值;例如

alt.Chart(df).transform_filter(
    alt.datum.foos > 0  
).mark_bar().encode(
    alt.X('foos', scale=alt.Scale(type='log')),
    y='group'
)

但即便如此,当与条形图一起使用时,对数尺度也会产生误导,因为条形图暗示条形和基线之间的线性比例是任意的。我建议使用线性刻度或不同类型的标记以使图表更清晰。

尝试使用 symlog(而不是日志)。