2025, Oct 19 02:46

Altair में डुप्लिकेट श्रेणियों के साथ प्रति पंक्ति बार कैसे पाएं

Altair बार चार्ट में डुप्लिकेट x-अक्ष लेबल से होने वाले अनचाहे एग्रीगेशन को रोकें. transform_calculate और labelExpr से यूनिक कुंजी बनाकर प्रति पंक्ति एक बार दिखाएँ.

Altair x-अक्ष पर एक ही श्रेणी साझा करने वाली पंक्तियों को समूहित करता है। यदि कोई फ़ील्ड दोहरती है, तो उसकी y-मूल्य जोड़ दिए जाते हैं, और परिणामस्वरूप बारों की संख्या पंक्तियों से कम हो जाती है। जब आपके स्रोत डेटा में जानबूझकर डुप्लिकेट हों और आप प्रति पंक्ति एक बार चाहते हों, तो आपको मूल लेबल दिखाते हुए भी x-चैनल के लिए एक अद्वितीय कुंजी चाहिए।

समस्या को दोहराना

डेटासेट में चार पंक्तियाँ हैं, जिनमें से दो प्रविष्टियों में फ़ील्ड a का मान समान है। सीधी-सादी Altair एन्कोडिंग इन्हें तीन बार में समेट देती है, क्योंकि B वाली दोनों पंक्तियों को जोड़ दिया जाता है।

data_tbl = pd.DataFrame({
    'a': ['A', 'B', 'C', 'B'],
    'b': [10, 20, 30, 15]
})
alt.Chart(data_tbl).mark_bar().encode(
    x='a',
    y='b'
)

इसके विपरीत, pandas से प्लॉट करने पर प्रति पंक्ति एक बार बनता है, क्योंकि वह हर रिकॉर्ड को स्वतंत्र मानता है, भले ही लेबल दोहर रहे हों।

data_tbl.plot(kind='bar', x='a', y='b')

कम बार क्यों दिखते हैं

इस व्यवस्था में a का मान समान होने वाली पंक्तियाँ मिलाई जाती हैं, इसलिए B वाली दोनों पंक्तियाँ जोड़कर एक ही बार में 35 दिखता है। नतीजा A, B और C के लिए तीन-बार का चार्ट होता है, न कि पंक्तियों की संख्या के अनुरूप अपेक्षित चार बार।

सरल समाधान और उसकी सीमा

DataFrame के इंडेक्स को x-चैनल बनाने से चार बार मिलते हैं, लेकिन लेबल संख्यात्मक इंडेक्स में बदल जाते हैं और अक्ष पर मूल a मान खो जाते हैं।

alt.Chart(data_tbl.reset_index()).mark_bar().encode(
    x='index:O',
    y='b'
)

यह पंक्तियों की संख्या तो बचा लेता है, पर इच्छित श्रेणी लेबल नहीं।

साफ समाधान: अद्वितीय x कुंजियाँ, मूल लेबल

पंक्ति इंडेक्स को a मान के साथ जोड़कर एक अद्वितीय x कुंजी बनाएं, और अक्ष पर केवल a वाला भाग दिखाएँ। इससे प्रति पंक्ति एक बार बना रहता है और x-अक्ष पर अपेक्षित पाठ भी बना रहता है।

alt.Chart(data_tbl.reset_index()).transform_calculate(
    x_token=alt.datum['a'] + '_' + alt.datum['index']
).mark_bar().encode(
    alt.X('x_token:N', title='A', axis=alt.Axis(labelExpr='split(datum.value, "_")[0]')),
    alt.Y('b')
)

यह ट्रांसफॉर्म प्रत्येक पंक्ति के लिए एक अद्वितीय समवर्ती कुंजी बनाता है। axis का labelExpr उस कुंजी को अंडरस्कोर पर विभाजित कर केवल बाएँ हिस्से को दिखाता है, जिससे संकलन रोका जाता है और अक्ष पर मूल a मान प्रभावी रूप से वापस आ जाते हैं।

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

जब आप अलग-अलग रिकॉर्ड दिखाने के लिए डुप्लिकेट श्रेणियों पर निर्भर करते हैं, तो पंक्तियों का चुपचाप मिल जाना चिह्नों की संख्या और बार की ऊँचाई दोनों बदल देता है। पंक्तियों और चिह्नों के बीच एक-से-एक मैपिंग सुनिश्चित करने से चार्ट बिना अनचाहे समेकन के मूल डेटा को प्रतिबिंबित करता है। साथ ही, मूल लेबल बचाए रखने से चार्ट पठनीय रहता है और डेटा के आशय के प्रति ईमानदार रहता है।

मुख्य बातें

जब आप प्रति पंक्ति एक बार की अपेक्षा करते हैं, पर श्रेणियाँ दोहरती हैं, तो एक अद्वितीय x-चैनल कुंजी बनाइए और अक्ष लेबल को नियंत्रित कीजिए ताकि मूल श्रेणियाँ दिखाई दें। यह तरीका समेकन से बचाता है, बारों की संख्या को पंक्तियों के बराबर रखता है और सार्थक लेबल बनाए रखता है।

यह लेख StackOverflow के एक प्रश्न पर आधारित है, जिसे MiscBits ने पूछा था, और एक उत्तर kgoodrick द्वारा दिया गया था।