2025, Nov 01 04:01

बिन-आधारित 2D काउंट ग्रिड का ध्रुवीय रूपांतरण और theta बनाम त्रिज्या प्लॉट

Python और matplotlib से 2D काउंट ग्रिड को ध्रुवीय निर्देशांकों में बदलने की विधि; theta बनाम त्रिज्या स्कैटर, cos(theta) की सीमाएं और सही मैपिंग के कदम.

किसी बिन-आधारित डिटेक्टर मैट्रिक्स को विश्लेषण के लिए उपयोगी रूप में बदलने की शुरुआत अक्सर सही निर्देशांक प्रणाली से होती है। यदि वितरण किसी ज्ञात केंद्र के चारों ओर लगभग वृत्ताकार दिखाई देता है, तो त्रिज्या और कोण के हिसाब से प्लॉट करने पर संरचना साफ उभर आती है। चुनौती प्लॉटिंग API नहीं, बल्कि मैपिंग है: बिन इंडेक्स के कार्टेशियन ग्रिड से एक ऐसा ध्रुवीय दृश्य कैसे लें जो सुसंगत और एकार्थक हो। नीचे इसी पद्धति का संक्षिप्त मार्गदर्शन दिया गया है—क्यों एक अक्ष पर cos(theta) प्लॉट करना निर्देशांक प्रणालियों को मिला देता है, और इसके बजाय स्वच्छ कोण–त्रिज्या विज़ुअलाइज़ेशन कैसे बनाया जाए।

समस्या की रूपरेखा

हमारे पास [x, y] इंडेक्स वाला द्वि-आयामी काउंट ग्रिड है। कुछ बिन शून्य हैं, कुछ को अनुपयोगी के रूप में चिह्नित किया गया है। रुचि का केंद्र (8, 8) पर है, और तेज कार्टेशियन विज़ुअलाइज़ेशन pcolor तथा दो मार्गदर्शक वृत्तों का उपयोग करता है।

import numpy as np
from matplotlib import pyplot as plt
from matplotlib.patches import Circle
counts_grid = np.asarray(
[[ 0.,  0.,  0.,  0.,  0.,  0.,  2.,  5.,  2.,  3.,  3.,  0.,  0.,  0.,  0.,  0.,  0.,  0.],
 [ 0.,  0.,  0.,  0.,  0.,  4., 10.,  9.,  7., 10.,  6.,  6.,  0.,  0.,  0.,  0.,  0.,  0.],
 [ 0.,  0.,  0.,  0.,  9., 12., 10., 11., 14., 13., 11., 12.,  6.,  0.,  0.,  0.,  0.,  0.],
 [ 0.,  0.,  0.,  0., 12., 16., 17., 14., 13., 14., 13., 12., 12.,  6.,  0.,  0.,  0.,  0.],
 [ 0.,  0., 10., 11.,  0., 14., 18., 16., 14., 18., 16., 14., 13.,  0.,  9.,  0.,  0.,  0.],
 [ 0.,  7., 10., 13., 13., 16., 16., 15., 14., 16., 13., 16., 13., 13., 13.,  7.,  0.,  0.],
 [ 1.,  6., 15., 14., 17., 14., 13., 13., 14., 15.,  1., 13., 13., 12., 12.,  7.,  2.,  0.],
 [ 5., 13., 11., 14., 12., 14., 14., 16., 16., 16., 12.,  1., 12., 14., 12.,  9.,  5.,  0.],
 [ 2., 11., 11., 16., 13., 17., 15., 14.,  0., 14., 14., 13., 13., 16., 10.,  9.,  6.,  1.],
 [ 4., 11., 13., 12., 14., 14., 16., 16., 14., 18., 16.,  1., 14., 12., 12., 11.,  5.,  1.],
 [ 1.,  7., 10., 11., 13., 14.,  1., 19., 15., 19.,  1.,  1., 14., 14., 11., 10.,  1.,  0.],
 [ 0.,  5., 10., 15., 14., 15., 16.,  1., 14.,  1.,  1., 16., 12., 13., 10.,  5.,  0.,  0.],
 [ 0.,  0.,  7., 12., 16., 15., 13., 17., 14., 16., 14., 14., 14., 14.,  7.,  0.,  0.,  0.],
 [ 0.,  0.,  0.,  7.,  0., 14., 14., 15., 16., 16., 14., 11., 13.,  0.,  0.,  0.,  0.,  0.],
 [ 0.,  0.,  0.,  0.,  8., 12., 14., 12., 14., 10., 11., 12.,  7.,  0.,  0.,  0.,  0.,  0.],
 [ 0.,  0.,  0.,  0.,  0.,  8.,  8., 11.,  9.,  9., 10.,  5.,  0.,  0.,  0.,  0.,  0.,  0.],
 [ 0.,  0.,  0.,  0.,  0.,  0.,  4.,  3.,  7.,  6.,  3.,  0.,  0.,  0.,  0.,  0.,  0.,  0.],
 [ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  2.,  0.,  1.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.]]
)/12
counts_grid[4][4] = None
counts_grid[-5][-5] = None
counts_grid[4][-5] = None
counts_grid[-5][4] = None
counts_grid[8][8] = None
# खराब सेल
counts_grid[6, 10] = None
counts_grid[10, 6] = None
counts_grid[7, 11] = None
counts_grid[11, 7] = None
counts_grid[11, 9] = None
counts_grid[11, 10] = None
counts_grid[10, 11] = None
counts_grid[9, 11] = None
counts_grid[10, 10] = None
fig_obj, axes_obj = plt.subplots()
plt.pcolor(counts_grid)
plt.colorbar(label="Count per hour")
ring = Circle((8.5, 8.5), 8, edgecolor='red', facecolor='none', linewidth=1)
axes_obj.add_patch(ring)
ring = Circle((8.5, 8.5), 6, edgecolor='red', facecolor='none', linewidth=1)
axes_obj.add_patch(ring)
plt.show()

वास्तव में क्या हो रहा है

लक्ष्य x-अक्ष पर cos(phi) और y-अक्ष पर केंद्र से दूरी रखना था। इस संदर्भ में तल के भीतर का कोण अधिक स्वाभाविक रूप से theta कहलाता है। cos(theta) को अक्ष के रूप में लेना निरूपणों को मिला देता है: x = r*cos(theta) ध्रुवीय से कार्टेशियन रूपांतरण का हिस्सा है, इसलिए एक अक्ष ध्रुवीय रूप में होगा और दूसरा नहीं। एक अस्पष्टता भी आती है: cos(theta) दो अलग-अलग कोणों को एक ही मान पर मैप करता है, इसलिए theta = pi/4 और theta = -pi/4 वाले बिंदु एक ही x-मूल्य पर आ धंसेंगे। यह तभी ठीक है जब आपका विश्लेषण स्पष्ट रूप से ऐसे दोहरेपन को चाहता हो।

वृत्तीय या रेडियल संरचना को जांचने का साफ तरीका है कि पूरी तरह ध्रुवीय निर्देशांकों में काम करें। चुने गए केंद्र के सापेक्ष हर बिन के केंद्र के लिए theta और त्रिज्या निकालें, फिर एक अक्ष पर theta और दूसरे पर त्रिज्या प्लॉट करें, और बिंदुओं का रंग उस बिन के काउंट से दर्शाएँ। इससे बिन और प्लॉटेड बिंदु के बीच एक-से-एक संबद्धता बनी रहती है, अनचाही फोल्डिंग से बचाव होता है, और रेडियल सममिति का दृश्य आकलन आसान हो जाता है।

समाधान: ग्रिड इंडेक्स को ध्रुवीय में बदलें और theta बनाम त्रिज्या का स्कैटर प्लॉट बनाएं

निम्न स्निपेट meshgrid से हर बिन इंडेक्स के लिए कार्टेशियन निर्देशांक बनाता है, मूल को (8, 8) पर शिफ्ट करता है, ऐरे को फ्लैट करता है, शून्य मान वाले बिन हटाता है, ध्रुवीय में बदलता है, और रंग के जरिए बिन काउंट दिखाते हुए theta बनाम त्रिज्या स्कैटर करता है।

x_idx = np.arange(counts_grid.shape[1])
y_idx = np.arange(counts_grid.shape[0])
xx, yy = np.meshgrid(x_idx, y_idx)
origin = (8, 8)
xx = xx - origin[0]
yy = yy - origin[1]
xx_vec = xx.flatten()
yy_vec = yy.flatten()
vals_vec = counts_grid.flatten()
# गैर-शून्य बिन रखें
keep = vals_vec != 0
xx_vec = xx_vec[keep]
yy_vec = yy_vec[keep]
vals_vec = vals_vec[keep]
angle = np.atan2(yy_vec, xx_vec)
radius = np.sqrt(xx_vec ** 2 + yy_vec ** 2)
plt.scatter(angle, radius, c=vals_vec, s=30)
plt.xlabel("Theta (radians)")
plt.ylabel("Radius (unknown unit)")
plt.colorbar(label="Count per hour")
plt.show()

यदि आगे के विश्लेषण में आपको स्पष्ट तौर पर cos(theta) चाहिए, तो स्कैटर कॉल को नीचे की पंक्ति से बदलकर प्लॉटिंग चरण में कोणीय निर्देशांक का प्रोजेक्शन कर सकते हैं। ध्यान रहे, इससे सममित कोण जान-बूझकर एक ही x-मूल्यों पर आ मिलेंगे।

plt.scatter(np.cos(angle), radius, c=vals_vec, s=30)

यह क्यों महत्वपूर्ण है

theta और त्रिज्या के साथ सीधे काम करना चित्रण को रेडियल ज्यामिति के अनुरूप कर देता है। यह अलग-अलग अक्षों पर ध्रुवीय और कार्टेशियन अवयवों के मिलावट से बचाता है, हर बिन को अनूठे रूप में रखता है, और त्रिज्या या कोण के साथ पैटर्न को देखना सरल बनाता है। शून्य मान वाले बिन हटाने से प्लॉट जानकारीपूर्ण कोशिकाओं पर केंद्रित रहता है और दृश्य अव्यवस्था घटती है। बाद में यदि आप cos(theta) से कोणीय आयाम को प्रोजेक्ट करना चाहें, तो आप यह समझते हुए करेंगे कि विपरीत कोण एक-दूसरे पर आ जाएँगे।

मुख्य बातें

जब 2D ग्रिड वृत्तीय सममिति का संकेत दे, तो रुचि के केंद्र के सापेक्ष ग्रिड इंडेक्स को ध्रुवीय पैमाने में बदलिए और theta बनाम त्रिज्या को दर्शाइए। meshgrid से बिन के कार्टेशियन निर्देशांक बनाइए, चुने गए मूल तक शिफ्ट कीजिए, atan2 से theta और sqrt से त्रिज्या निकालिए, और काउंट्स से बिंदुओं को रंगिए। cos(theta) उसी स्थिति के लिए बचाकर रखें जब सममित कोणों को जान-बूझकर समेटना उद्देश्य हो; अन्यथा, बिना अस्पष्टता के दृश्य के लिए theta को जस का तस रखें।

यह लेख StackOverflow पर प्रश्न (लेखक: David K.) और Nick ODell के उत्तर पर आधारित है।