亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

在 Altair 中,如何正確地將面積圖中的基線移動到特定的 y 位置并相應地更改填充顏色?

在 Altair 中,如何正確地將面積圖中的基線移動到特定的 y 位置并相應地更改填充顏色?

HUX布斯 2023-07-05 18:00:16
我希望能夠做這樣的事情 -注意:你看到的水平線不是在 y=0 處,而是在 y=1 處但使用color或fill編碼condition在面積圖中并不真正有效。我得到的最接近的是使用yOffset(命中并嘗試以獲得完美值),但mark_area最大的問題是 y 軸保持不變,因此圖表實際上變得無效。示例:(忽略水平連接的圖表 - 這只是為了能夠得出一個好的值,因為yOffsety 軸根本不移動。)import pandas as pddata = 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, 0.8, 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',    y='stock:Q',    fill = alt.condition(alt.datum.stock<1, alt.value('grey'), alt.value('red')))left | right輸出右側的圖表非常接近 - y 軸值和顏色是錯誤的。有沒有辦法在 Altair 中做這樣的事情?編輯1:我嘗試了這篇文章中的想法,它有點相似,但它并不像我想象的那樣工作 -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輸出
查看完整描述

1 回答

?
素胚勾勒不出你

TA貢獻1827條經驗 獲得超9個贊

您可以通過參數提供第二個 y 編碼來將基線定義為 1 y2。使用這種方法與條形圖相對簡單:


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, 0.8, 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')))

http://img1.sycdn.imooc.com//64a53f850001d03c04900380.jpg

這很有效,因為條形是單獨的圖形元素,因此它們將單獨著色。面積圖是單個圖形元素,因此僅針對第一個庫存值執行條件比較,然后整個區域都以此顏色著色。為了獲得不同的顏色,我們需要將區域分成多個標記,如您鏈接的答案中所示進行分組(這也適用于條形圖)。您可以通過預先在數據框中創建分組列或通過transform_calculate.


(alt.Chart(data.reset_index()).mark_area().encode(

    x=alt.X('date:T'),

    y=alt.Y('stock:Q', impute={'value': 1}),

    y2='baseline',

    color=alt.Color('negative:N', scale=alt.Scale(range=['red', 'grey'])))

 .transform_calculate(negative='datum.stock < 1'))

http://img1.sycdn.imooc.com//64a53f940001067b05560375.jpg

為什么點之間存在重疊?其原因是數據的稀疏性以及區域和線標記的默認插值方法是“線性”。如果將其更改為mark_area(interpolate='step'),區域之間的邊界將變得清晰:

http://img1.sycdn.imooc.com//64a53fa30001b46d05590380.jpg

為了在保持其形狀的同時實現基線周圍區域標記的急劇過渡,數據需要具有更高分辨率。借用您鏈接的答案,您可以看到當數據稀疏時,那里的區域也會重疊:


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'))

http://img1.sycdn.imooc.com//64a53fae0001894b05650380.jpg

如果我們將點數增加十倍 ( x = np.linspace(2, 4, 40)),隨著插值發生在空間中更接近的點之間,過渡會變得更加尖銳(將插值從線性更改為單調,在保持形狀的同時也可能有所幫助)。

http://img1.sycdn.imooc.com//64a53fc20001c6ee05600375.jpg

要提高時間序列數據的分辨率,您可以使用 pandasresample和interpolate方法進行上采樣。做這樣的事情時要擔心的是,您是否以有意義的方式人為地更改了數據。我發現問問自己該操作是否會改變您對數據得出的結論很有用。


(alt.Chart(data.set_index('date').resample('1h').interpolate().reset_index()).mark_area().encode(

    x=alt.X('date:T'),

    y=alt.Y('stock:Q', impute={'value': 1}),

    y2='baseline',

    color=alt.Color('negative:N', scale=alt.Scale(range=['red', 'grey'])))

 .transform_calculate(negative='datum.stock < 1'))

http://img1.sycdn.imooc.com//64a53fd10001436705570378.jpg

在這里,我們上采樣到每小時的數據點,并在原始點之間進行線性插值。對我來說,這不會改變我通過研究該圖得出的結論,因為線性插值保留了區域的塊狀外觀,因此我們不會使數據看起來人為平滑。我想到的唯一缺點是,我們確實向 Altair 發送了不必要的數據量,您也許可以使用 Altair 中的轉換來執行插值,但我不知道該怎么做。



查看完整回答
反對 回復 2023-07-05
  • 1 回答
  • 0 關注
  • 137 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號