2025, Nov 01 19:31

Altair में error bars के साथ लेयर्ड बार चार्ट को Y-आधारित X क्रम में रखें

Altair में लेयर्ड बार चार्ट में error bars जोड़ने पर X अक्ष का sort बिगड़ता है? EncodingSortField से Y-आधारित क्रम स्थिर रखें—समस्या की वजह और कोड समाधान देखें.

Altair में लेयर्ड चार्ट बार्स को इंटरवल्स या अनिश्चितता बैंड्स के साथ जोड़ने का удобный шаблон हैं। अक्सर जरूरत होती है कि X अक्ष को Y पर आधारित मात्रात्मक मान के अनुसार क्रमबद्ध किया जाए। बार्स और रूल्स के साथ यह सरल चलता है, लेकिन जैसे ही एरर बार्स शामिल होते हैं, मामला उलझ जाता है: वही सॉर्ट अचानक वर्णानुक्रम में लौट आता है।

समस्या को पुन: उत्पन्न करना

नीचे दिया उदाहरण एक बार चार्ट को या तो रूल्स या एरर बार्स के साथ लेयर करता है। Y मीट्रिक के आधार पर X अक्ष को सॉर्ट करना रूल्स के साथ काम करता है, पर एरर बार्स के साथ नहीं, जबकि हर लेयर अकेले चलाने पर सही सॉर्ट होती है।

import polars as pl
import altair as alt
data_tbl = pl.DataFrame({
    "label": ["A", "B", "C", "D"],
    "avg": [1.2, 2.5, 0.9, 3.1],
    "lo": [1.0, 2.2, 0.85, 2.8],
    "hi": [1.4, 2.8, 0.95, 3.4]
})
base_cols = alt.Chart(data_tbl).mark_bar().encode(
    x=alt.X("label:N").sort("-y"),
    y=alt.Y("avg:Q")
)
err_overlay = base_cols.mark_errorbar().encode(
    y="lo:Q",
    y2="hi:Q"
)
rule_overlay = base_cols.mark_rule().encode(
    y="lo:Q",
    y2="hi:Q"
)
# सॉर्ट नहीं होता
base_cols + err_overlay
# सॉर्ट हो जाता है
base_cols + rule_overlay

हर लेयर अलग से देखने पर सही सॉर्ट होती है। लेकिन जब बार्स + एरर बार्स को मिलाते हैं, तो X अक्ष फिर से वर्णानुक्रम में चला जाता है, जबकि बार्स + रूल्स Y के अनुसार सॉर्ट का सम्मान करते हैं।

मुद्दा क्या है

देखे गए व्यवहार का कारण सॉर्ट निर्दिष्ट करने का तरीका है। X पर "-y" जैसा शॉर्टहैंड स्ट्रिंग-आधारित सॉर्ट, एरर बार्स के साथ लेयर करने पर अनदेखा हो सकता है, जबकि यही शॉर्टहैंड रूल्स के साथ ठीक चलता है। व्यावहारिक अर्थ यह है कि लेयर्ड चार्ट में mark_errorbar के लिए Y चैनल के इम्प्लिसिट सॉर्ट को हमेशा नहीं माना जाता। स्पष्ट, फील्ड-आधारित सॉर्ट इस्तेमाल करने से यह असंगति दूर हो जाती है।

समाधान

X चैनल पर EncodingSortField के जरिए सॉर्ट तय करें और उसे उसी मात्रात्मक मीट्रिक पर इंगित करें जो क्रम तय करना चाहिए। इससे एरर बार्स के साथ लेयरिंग करने पर भी सही क्रम बना रहता है।

import polars as pl
import altair as alt
data_tbl = pl.DataFrame({
    "label": ["A", "B", "C", "D"],
    "avg": [1.2, 2.5, 0.9, 3.1],
    "lo": [1.0, 2.2, 0.85, 2.8],
    "hi": [1.4, 2.8, 0.95, 3.4]
})
base_cols = alt.Chart(data_tbl).mark_bar().encode(
    x=alt.X("label:N").sort(alt.EncodingSortField(field="avg", op="min")),
    y=alt.Y("avg:Q")
)
err_overlay = base_cols.mark_errorbar().encode(
    y="lo:Q",
    y2="hi:Q"
)
# अब सही तरह से सॉर्ट होता है
base_cols + err_overlay

और विवरण: github issue.

यह क्यों मायने रखता है

अक्षों का क्रम सिर्फ दिखावे की बात नहीं है। यही तय करता है कि रैंकिंग, चरम मान और पैटर्न एक नज़र में कैसे पढ़े जाते हैं। जब mark_errorbar के साथ अनिश्चितता लेयर करते हैं, तो डिफॉल्ट शॉर्टहैंड सॉर्ट चुपचाप वर्णानुक्रम में बदल सकता है, जिससे तुलना धुंधली हो जाती है। एक स्पष्ट EncodingSortField इच्छित मीट्रिक से सॉर्ट को जोड़कर रखता है और चार्ट को लेयरिंग की बारीकियों के प्रति मजबूत बनाता है।

मुख्य बातें

यदि आपको लेयर्ड चार्ट के X अक्ष को Y-आधारित मान से सॉर्ट करना है और आप एरर बार्स जोड़ते हैं, तो X चैनल पर EncodingSortField के साथ स्पष्ट सॉर्ट को प्राथमिकता दें। उसे उसी मात्रात्मक फील्ड पर इंगित करें जो बार की ऊंचाई को नियंत्रित कर रही है, और अपने डिज़ाइन के अनुरूप एग्रीगेशन बताएं। यह छोटा सा बदलाव अप्रत्याशित पुन:क्रमण से बचाता है और आपके लेयर्ड विज़ुअलाइज़ेशन को सुसंगत रखता है।

यह लेख StackOverflow पर प्रश्न (लेखक: sasha) और kgoodrick के उत्तर पर आधारित है।