如何在Altair中将区域图中的基线正确地移动到特定的y位置并相应地更改填充颜色?

如何解决如何在Altair中将区域图中的基线正确地移动到特定的y位置并相应地更改填充颜色?

我希望能够做这样的事情-

enter image description here


注意:您看到的水平线不在y = 0,而是y = 1

但是将colorfill一起使用conditionyOffset编码在面积图中实际上不起作用。

我最接近的是在mark_area中使用yOffset(为达到最佳值而进行命中和尝试),但是最大的问题是y轴保持不变,因此图表实际上变为无效

示例
(忽略水平连接的图表-只是因为y轴完全不移动,所以能够为import pandas as pd data = pd.DataFrame({'date': pd.date_range(start='1/1/2018',end='1/11/2018'),'stock': [0.1,0.3,0.9,1,1.5,1.2,0.8,1.1,0.4,1.6]}) left = alt.Chart(data).mark_area().encode( x='date:T',y='stock:Q',fill = alt.condition(alt.datum.stock<1,alt.value('grey'),alt.value('red')) ) right = alt.Chart(data).mark_area(yOffset=190,).encode( x='date:T',alt.value('red')) ) left | right 给出一个很好的值。)

trial1 = alt.Chart(data).mark_area().transform_calculate(below=alt.datum.stock<=1).encode(
    x='date:T',y=alt.Y('stock:Q'),color = 'below:N'
)

trial2 = alt.Chart(data).mark_area().transform_calculate(below=alt.datum.stock<=1).encode(
    x='date:T',y=alt.Y('stock:Q',impute={'value': 1}),color = 'below:N'
)
trial1|trial2

输出

enter image description here

右侧的图表非常接近-y轴值和颜色错误

altair中有没有办法做类似的事情?

编辑1
我从这个post尝试了一个想法,这个想法有点相似,但是它不起作用,就像我想的那样-

import axios from 'axios';

export default axios.create({
    baseURL:"https://api.twitter.com/2/",header: {"Authorization": "Bearer $mybearertoken"}
});

输出

enter image description here

解决方法

您可以通过 y2 参数提供第二个 y 编码,将基线定义为 1。将此方法用于条形图相对简单:

import pandas as pd
import altair as alt


data = pd.DataFrame(
    {'date': pd.date_range(start='1/1/2018',end='1/11/2018'),'stock': [0.1,0.3,0.9,1,1.5,1.2,0.8,1.1,0.4,1.6],'baseline': [1]*11})

# You could also set the bar width instead of binning
alt.Chart(data).mark_bar().encode(
    x=alt.X('monthdate(date):T'),y='stock:Q',y2='baseline',color = alt.condition(alt.datum.stock < 1,alt.value('grey'),alt.value('red')))

enter image description here

这很有效,因为条形是单独的图形元素,因此它们将单独着色。面积图是单个图形元素,因此仅针对第一个股票值执行条件比较,然后整个区域都以这种颜色着色。为了获得不同的颜色,我们需要按照您链接的答案(这也适用于条形图)进行分组,将区域分成多个标记。您可以通过预先在数据框中创建一个分组列或通过 transform_calculate 来做到这一点。

(alt.Chart(data.reset_index()).mark_area().encode(
    x=alt.X('date:T'),y=alt.Y('stock:Q',impute={'value': 1}),color=alt.Color('negative:N',scale=alt.Scale(range=['red','grey'])))
 .transform_calculate(negative='datum.stock < 1'))

enter image description here

为什么点之间有重叠?其原因是数据的稀疏性以及区域和线标记的默认插值方法是“线性”。如果您将其更改为 mark_area(interpolate='step'),则区域之间的边界会很清晰:

enter image description here

要在保持其形状的同时实现基线周围区域标记的急剧过渡,数据需要具有更高的分辨率。借用您链接的答案,您可以看到,当数据稀疏时,那里的区域也会重叠:

import altair as alt
import pandas as pd
import numpy as np


x = np.linspace(2,4,4)
df = pd.DataFrame({'x': x,'y': np.sin(x)})

(alt.Chart(df).mark_area().encode(
    x='x',y=alt.Y('y',impute={'value': 0}),color='negative:N')
 .transform_calculate(negative='datum.y < 0'))

enter image description here

如果我们将点的数量增加十倍 (x = np.linspace(2,40)),随着插值发生在空间中更近的点之间,过渡变得更加尖锐(将插值从线性更改为单调,在保留形状的同时也可能有所帮助).

enter image description here

要提高时间序列数据的分辨率,您可以使用 pandas resampleinterpolate 方法进行上采样。做这样的事情时担心的是,如果你以一种有意义的方式人为地改变了你的数据。我发现问问自己操作是否会改变您对数据得出的结论很有用。

(alt.Chart(data.set_index('date').resample('1h').interpolate().reset_index()).mark_area().encode(
    x=alt.X('date:T'),'grey'])))
 .transform_calculate(negative='datum.stock < 1'))

enter image description here

在这里,我们对每小时的数据点进行了上采样,并在原始点之间进行了线性插值。对我来说,这不会改变我从研究图中得出的结论,因为线性插值保留了区域的块状外观,因此我们不会人为地使数据看起来平滑。唯一想到的缺点是我们确实向 Altair 发送了不必要的数据量,您也许可以使用 Altair 中的变换来执行插值,但我不确定如何实现。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?