मुख्य सामग्री पर जाएँ

Plotly आकृतियाँ: प्लॉट्स में एनोटेशन और स्टाइलिंग के लिए एक गाइड

Plotly आकृतियों के साथ अपनी डेटा स्टोरीटेलिंग को ऊँचाई दें। यह गाइड Python में बुनियादी आयतों और रेखाओं से लेकर उन्नत इंटरैक्टिव ज्यामितियों तक, एनोटेशन जोड़ने और स्टाइल करने का व्यापक वॉकथ्रू प्रदान करता है।
· 12 मि॰ पढ़ें

AI के साथ खोजें

Plotly इंटरैक्टिव ग्राफ बनाने के लिए सबसे शक्तिशाली और लोकप्रिय Python लाइब्रेरीज़ में से एक है। जहाँ Plotly के साथ बेसिक चार्ट बनाना आसान है, वहीं सचमुच प्रभावशाली डेटा विज़ुअलाइज़ेशन के लिए अक्सर ऐसे अतिरिक्त तत्वों की जरूरत होती है जो दर्शक का ध्यान निर्देशित करें और महत्वपूर्ण संदर्भ प्रदान करें। यहीं पर Plotly shapes बेहद उपयोगी साबित होते हैं।

Shapes आयत, रेखाएँ, और वृत्त जैसे ग्राफिकल एलिमेंट होते हैं जिन्हें आप अपने Plotly फिगर पर ओवरले करके एनोटेट, हाईलाइट, और ज़रूरी संदर्भ जोड़ सकते हैं। ये एक साधारण प्लॉट को समृद्ध, सूझबूझ भरा और प्रकाशन-योग्य विज़ुअलाइज़ेशन में बदलने की कुंजी हैं।

plotly shapes

छवि: लेखक द्वारा

इस लेख में, हम plotly shapes के बारे में वह सब कुछ देखेंगे जो आपको जानना चाहिए—बेसिक इम्प्लिमेंटेशन से लेकर उन्नत कस्टमाइज़ेशन तकनीकों तक। जो लोग Plotly में नए हैं, उनके लिए इसके हाई-लेवल इंटरफेस से सहज होना एक अच्छा पहला कदम है, और यह Introduction to Data Visualization with Plotly in Python कोर्स आपको shapes जैसी गहन कस्टमाइज़ेशन में जाने से पहले बुनियादी बातों में माहिर होने में मदद कर सकता है।

Plotly Shapes क्या हैं?

Plotly shapes वेक्टर ग्राफिक्स होते हैं जिन्हें किसी फिगर पर अतिरिक्त संदर्भ देने या विशिष्ट क्षेत्रों को हाईलाइट करने के लिए बनाया जाता है। ये एनोटेशन ऐसे ग्राफ बनाने में महत्वपूर्ण हैं जो सिर्फ आकर्षक ही नहीं बल्कि सूचना-संपन्न भी हों।

डेटा विज़ुअलाइज़ेशन में shapes का महत्व

डेटा विज़ुअलाइज़ेशन में स्पष्टता सबसे अहम है। स्कैटर प्लॉट या बार ग्राफ जैसे चार्ट डेटा तो दिखाते हैं, लेकिन shapes डेटा के पीछे की कहानी बताने में मदद करते हैं। इनके दो मुख्य कार्य हैं:

  • डेटा ट्रेंड्स को हाईलाइट करना: Shapes आपके डेटा के भीतर मुख्य अवधियों या घटनाओं पर ध्यान आकर्षित कर सकते हैं। उदाहरण के लिए, आप GDP के टाइम-सीरीज़ ग्राफ पर मंदी की अवधि को शेड करने के लिए एक आयत का उपयोग कर सकते हैं या किसी महत्वपूर्ण नीतिगत बदलाव को दर्शाने के लिए एक रेखा खींच सकते हैं। यह विज़ुअल संकेतक दर्शक को बाहरी कारकों के प्रभाव को तुरंत समझने में मदद करता है।
  • संदर्भात्मक एनोटेशन प्रदान करना: Shapes विशिष्ट डेटा बिंदुओं या क्लस्टर्स—जैसे आउट्लायर, रुचि-समूह, या क्रिटिकल थ्रेशहोल्ड—को घेरे में ले सकते हैं या उन पर संकेत कर सकते हैं। कल्पना करें एक क्वालिटी कंट्रोल चार्ट की, जहाँ आप स्वीकृत सीमाओं से बाहर आने वाले मापों को चिह्नित करने के लिए वृत्तों का उपयोग करते हैं। यह डेटा की व्याख्या को तेज़ और अधिक सहज बनाता है।

यदि आप सबसे आम डेटा विज़ुअलाइज़ेशन्स, उनका उपयोग कब करें, और उनके सर्वाधिक सामान्य उपयोग-केस का त्वरित अवलोकन चाहते हैं, तो हमारा Data Visualization चीट शीट देखें।

Plotly में shape प्रकारों का अवलोकन

Plotly ऐसी कई ज्यामितीय shape प्रकारों का समर्थन करता है जिन्हें किसी फिगर के लेआउट में जोड़ा जा सकता है। प्रत्येक को उसके type और विशिष्ट निर्देशांक पैरामीटर्स द्वारा परिभाषित किया जाता है।

मुख्य shapes पर एक संक्षिप्त नज़र:

  • Rectangle (type: 'rect'): दो विपरीत कोनों (x0, y0) और (x1, y1) से परिभाषित। रुचि के क्षेत्रों को शेड करने या डेटा की किसी विशिष्ट विंडो को हाईलाइट करने के लिए उपयुक्त।
  • Line (type: 'line'): एक प्रारंभ बिंदु (x0, y0) और एक अंत बिंदु (x1, y1) से परिभाषित। ट्रेंडलाइन, थ्रेशहोल्ड, या रेफरेंस मार्क बनाने के लिए उत्कृष्ट।
  • Circle (type: 'circle'): केंद्र (x0, y0) और त्रिज्या से परिभाषित। व्यक्तिगत डेटा बिंदुओं या छोटे क्लस्टर्स पर जोर देने के लिए आदर्श। ध्यान दें कि वृत्त बनाने के लिए अक्सर अक्षों के लिए समान आस्पेक्ट अनुपात सेट करना पड़ता है (fig.update_layout(yaxis_scaleanchor="x")), ताकि वह दीर्घवृत्त जैसा न दिखे।
  • Path (type: 'path'): एक SVG पाथ स्ट्रिंग से परिभाषित। Paths आपको जटिल, फ्रीफॉर्म shapes—जिनमें बहुभुज भी शामिल हैं—खींचने देते हैं। आप कोई भी shape बनाने के लिए कमांडों का क्रम देते हैं (जैसे M मूव, L लाइन-टू, Z क्लोज पाथ)। यह कस्टम ज्यामितीय एनोटेशन बनाने का सबसे लचीला विकल्प है।

इन बेसिक प्रकारों को समझना आपके Plotly फिगर्स में विज़ुअल एनोटेशन में महारत हासिल करने की पहली सीढ़ी है।

Plotly ग्राफ़्स में Shapes जोड़ना

अपनी विज़ुअलाइज़ेशन्स में plotly shapes लागू करने के लिए दो प्राथमिक तरीकों को समझना होता है: व्यक्तिगत shapes के लिए add_shape() मेथड और एक से अधिक shapes के लिए update_layout() तरीका। आपकी ज़रूरत और कार्यप्रवाह के अनुसार दोनों के अपने फायदे हैं। आइए add_shape() मेथड का उपयोग करके shapes जोड़ना देखें।

add_shape() का उपयोग करके shapes कैसे जोड़ें?

किसी Plotly फिगर में एक सिंगल shape जोड़ने का प्राथमिक तरीका है fig.add_shape()। add_shape() मेथड plotly.graph_objects.Figure ऑब्जेक्ट का एक फ़ंक्शन है। आप पहले अपना बेस फिगर (जैसे स्कैटर प्लॉट या लाइन चार्ट) बनाते हैं, और फिर इस मेथड को कॉल करके उसके ऊपर shape को लेयर करते हैं। 

जब आपको कुछ शर्तों या डेटा मानों के आधार पर प्रोग्रामेटिक रूप से shapes जोड़ने होते हैं, तो यह विशेष रूप से उपयोगी होता है। आइए एक बेसिक उदाहरण देखें जहाँ हम टाइम-सीरीज़ प्लॉट पर एक विशिष्ट क्षेत्र को हाईलाइट करते हैं।

import plotly.graph_objects as go
import numpy as np

# Create sample data
x = np.linspace(0, 10, 100)
y = np.sin(x) + np.random.normal(0, 0.1, 100)

# Create base figure
fig = go.Figure()
fig.add_trace(go.Scatter(x=x, y=y, mode='lines', name='Signal'))

# Add a shape using add_shape method
fig.add_shape(
    type="rect",           # Shape type
    x0=2, x1=4,           # X coordinates
    y0=-2, y1=2,          # Y coordinates
    fillcolor="rgba(255, 0, 0, 0.3)",  # Fill color with transparency
    line=dict(color="red", width=2)     # Border styling
)

fig.show()

आउटपुट:

Plotly add shapes using add_shape()

Plotly का add_shape() फ़ंक्शन तब विशेष रूप से शक्तिशाली हो जाता है जब आप कोऑर्डिनेट सिस्टम समझ लेते हैं। Shapes xref और yref पैरामीटर्स का उपयोग करके अलग-अलग कोऑर्डिनेट सिस्टम को संदर्भित कर सकते हैं। ये कोऑर्डिनेट फ़्रेम निर्दिष्ट करते हैं: मानों को डेटा यूनिट्स में समझने के लिए 'x'/'y' का उपयोग करें, या सामान्यीकृत प्लॉट क्षेत्र के लिए 'paper' का उपयोग करें जहाँ 0–1 बाएँ-नीचे से दाएँ-ऊपर तक पूरी चौड़ाई/ऊँचाई को कवर करता है। आइए ऊपर दिए गए ग्राफ़ को इन पैरामीटर्स का उपयोग करके निम्नानुसार संशोधित करें:

# Shape referenced to data coordinates (default)
fig.add_shape(type="line", x0=1, x1=9, y0=0, y1=0,
              line=dict(color="green", width=3))

# Shape referenced to paper coordinates (0-1 scale)
fig.add_shape(type="rect", xref="paper", yref="paper",
              x0=0.1, x1=0.9, y0=0.1, y1=0.9,
              fillcolor="rgba(0, 0, 255, 0.1)")

आउटपुट:

Rectangles और lines को कस्टमाइज़ करना

एनोटेशन के लिए आयत और रेखाएँ सबसे आम shapes हैं। Plotly उनके स्वरूप को नियंत्रित करने के लिए व्यापक कस्टमाइज़ेशन विकल्प प्रदान करता है। सामान्य Plotly सिंटैक्स पर त्वरित संदर्भ के लिए Plotly Express चीट शीट अमूल्य संसाधन है। आइए देखें इन्हें कैसे कस्टमाइज़ करें।

Rectangle shape कस्टमाइज़ेशन

आयत दो बिंदुओं (x0,y0 और x1, y1) से परिभाषित होते हैं। आप फिल और बॉर्डर को अलग-अलग स्टाइल कर सकते हैं।

# Advanced rectangle customization
fig.add_shape(
    type="rect",
    x0=3, x1=7,
    y0=-1.5, y1=1.5,
    # Fill properties
    fillcolor="rgba(50, 171, 96, 0.4)",
    # Line properties
    line=dict(
        color="darkgreen",
        width=3,
        dash="dashdot"  # Options: solid, dot, dash, longdash, dashdot
    ),
    # Layer control
    layer="below"  # Options: above, below
)

आउटपुट:

Plotly Rectangle Shape Customization

Line shape कस्टमाइज़ेशन

रेखाएँ क्षैतिज और ऊर्ध्वाधर रेखाओं के लिए विशेषीकृत ‘add_hline’ और ‘add_vline’ मेथड से जोड़ी जा सकती हैं जो पूरे प्लॉट में फैली होती हैं, या अधिक सटीक नियंत्रण के लिए सामान्य ‘add_shape’ मेथड के माध्यम से। आइए एक उदाहरण देखें:

# Horizontal threshold lines
fig.add_hline(y=1.0, line_dash="dash", line_color="red", 
              annotation_text="Upper Threshold")
fig.add_hline(y=-1.0, line_dash="dash", line_color="red", 
              annotation_text="Lower Threshold")

# Custom diagonal line
fig.add_shape(
    type="line",
    x0=0, x1=10,
    y0=-2, y1=2,
    line=dict(
        color="purple",
        width=4,
        dash="longdashdot"
    )
)

आउटपुट:

Plotly Line shape customization

ये उदाहरण दिखाते हैं कि आप कितनी आसानी से बुनियादी Plotly shapes जोड़ और स्टाइल कर सकते हैं ताकि आपके ग्राफ अधिक सूचनाप्रद बनें।

एडवांस्ड कॉन्फ़िगरेशन और कस्टमाइज़ेशन

बेसिक shapes जोड़ने से आगे, Plotly कई shapes प्रबंधित करने और उनके विज़ुअल हायरार्की को नियंत्रित करने के शक्तिशाली टूल्स देता है। ये उन्नत सुविधाएँ जटिल, लेयर्ड और डायनेमिक विज़ुअलाइज़ेशन्स बनाने के लिए आवश्यक हैं। आइए कुछ तरीकों से ग्राफ़्स को कॉन्फ़िगर और कस्टमाइज़ करना देखें।

डायनेमिक अपडेट्स के लिए plotly.update_layout का उपयोग

जहाँ add_shape() मेथड एक-एक करके shapes जोड़ने के लिए उपयुक्त है, वहीं update_layout() मेथड प्रोग्रामेटिक रूप से जनरेट हुए shapes के संग्रह को मैनेज करने का अधिक कुशल तरीका है। प्रत्येक shape के लिए अलग फ़ंक्शन कॉल करने के बजाय, आप update_layout() के भीतर shapes आर्गुमेंट को सीधे shape डिक्शनरीज़ की एक सूची पास कर सकते हैं। 

आइए इस मेथड का एक उदाहरण देखें:

import plotly.graph_objects as go
import numpy as np

# Sample scatter plot data
x_data = np.linspace(0, 10, 50)
y_data = np.sin(x_data) + np.random.normal(0, 0.1, 50)

fig = go.Figure(data=go.Scatter(x=x_data, y=y_data, mode='markers', name='Data Points'))

# Define a list of shapes to add
shapes_to_add = [
    # A rectangle highlighting a peak area
    dict(
        type="rect",
        x0=1, x1=2.5, y0=0.8, y1=1.2,
        fillcolor="rgba(255, 165, 0, 0.4)",
        line_width=0
    ),
    # A vertical line marking an event
    dict(
        type="line",
        x0=7.5, x1=7.5, y0=0, y1=1,
        yref="paper", # Span the full plot height
        line=dict(color="red", width=2, dash="dot")
    )
]

# Add all shapes at once using update_layout
fig.update_layout(
    shapes=shapes_to_add
)

fig.show()

आउटपुट:

Using plotly.update_layout for dynamic updates

यह तरीका डायनेमिक अनुप्रयोगों—जैसे Dash डैशबोर्ड, जहाँ shapes को यूज़र इनपुट के आधार पर बदलना पड़ता है—के लिए खास तौर पर शक्तिशाली है। आप shape ऑब्जेक्ट्स की नई सूची जनरेट कर सकते हैं और एक ही, साफ़ ऑपरेशन में लेआउट अपडेट कर सकते हैं। यह अप्रोच आपके कोड को व्यवस्थित रखता है और एक साथ बड़ी संख्या में shapes जोड़ने के लिए आम तौर पर अधिक प्रदर्शनकारी होता है।

लेयरिंग और z-index नियंत्रण

जब आप किसी प्लॉट में shapes जोड़ते हैं, तो यह नियंत्रित करना महत्वपूर्ण है कि वे आपके डेटा के ऊपर दिखें या पीछे। Plotly इसे layer प्रॉपर्टी के माध्यम से मैनेज करता है। हालाँकि यह CSS जैसा सूक्ष्म z-index नहीं है, लेकिन यह विज़ुअल स्टैकिंग पर आवश्यक नियंत्रण देता है।

layer प्रॉपर्टी को दो मानों में से किसी एक पर सेट किया जा सकता है:

  • 'above': shape डेटा ट्रेसेज़ के ऊपर ड्रॉ होता है। यह डिफ़ॉल्ट सेटिंग है और उन एनोटेशन्स के लिए उपयोगी है जिन्हें स्पष्ट रूप से दिखना चाहिए।
  • 'below': shape डेटा ट्रेसेज़ और ग्रिडलाइनों के नीचे ड्रॉ होता है। यह बैकग्राउंड शेडिंग या क्षेत्रों को हाईलाइट करने के लिए उपयुक्त है, बिना डेटा बिंदुओं को ढँके।

सूची shapes के भीतर shapes का क्रम भी मायने रखता है: सूची में बाद में परिभाषित shapes (उसी layer के भीतर) पहले परिभाषित shapes के ऊपर ड्रॉ होंगी।

लेयरिंग के प्रभाव को दर्शाने वाला एक उदाहरण यहाँ है:

import plotly.graph_objects as go

fig = go.Figure(data=go.Scatter(x=[1, 2, 3, 4, 5], y=[5, 3, 4, 2, 6], mode='markers', marker_size=20, name='Data'))

# Add a shape BELOW the data points
fig.add_shape(
    type="rect",
    x0=2.5, y0=2.5, x1=4.5, y1=4.5,
    fillcolor="LightPink",
    opacity=0.8,
    layer="below", # Key parameter
    line_width=0
)

# Add a shape ABOVE the data points
fig.add_shape(
    type="circle",
    x0=0.5, y0=4.5, x1=1.5, y1=5.5,
    fillcolor="LightSeaGreen",
    opacity=0.6,
    layer="above", # Key parameter
    line_width=0
)

fig.update_layout(
    xaxis=dict(showgrid=False), # Turn off gridlines to see effect clearly
    yaxis=dict(showgrid=False)
)

fig.show()

आउटपुट:

Layering and z-index control

जैसा कि आप देख सकते हैं, गुलाबी आयत मार्कर्स के पीछे है, जबकि हरा वृत्त डेटा बिंदु के ऊपर ओवरले होता है। 

इन लेआउट और लेयरिंग तकनीकों में महारत हासिल करना Plotly के साथ उन्नत और इंटरैक्टिव डेटा विज़ुअलाइज़ेशन बनाने का एक अहम हिस्सा है। जो लोग R में काम करते हैं, उनके लिए भी समान अवधारणाएँ लागू होती हैं, जैसा कि Intermediate Interactive Data Visualization with Plotly in R में खोजा गया है।

इंटरैक्टिव shape एडिटिंग

Plotly की सबसे शक्तिशाली विशेषताओं में से एक है इसकी इंटरैक्टिविटी। आप Plotly shapes को editable बना सकते हैं, जिससे उपयोगकर्ता प्लॉट पर ही उन्हें ड्रैग, रिसाइज़ और रोटेट कर सकें। यह सुविधा shape की परिभाषा में editable=True सेट करके सक्षम होती है। आइए देखें यह कैसे किया जाता है:

import plotly.graph_objects as go
import numpy as np

# Create a scatter plot
fig = go.Figure(go.Scatter(
    x=np.random.rand(100),
    y=np.random.rand(100),
    mode='markers'
))

# Add a draggable rectangle
fig.add_shape(
    type="rect",
    x0=0.2, y0=0.2, x1=0.5, y1=0.5,
    line=dict(color="RoyalBlue", width=2),
    fillcolor="LightSkyBlue",
    opacity=0.5,
    editable=True # This makes the shape interactive
)

fig.update_layout(
    xaxis=dict(range=[0, 1]),
    yaxis=dict(range=[0, 1]),
    # The 'newshape' button in the modebar allows drawing new shapes
    # The config dictionary enables editing of existing shapes
    dragmode='select'
)

# To enable editing, the modebar must be visible (default) which you will see when hovering over the graph with the mouse.

# and the plot's config can ensure editing tools are available.
fig.show(config={'edits': {'shapePosition': True}})

आउटपुट:

इंटरैक्टिव shapes खोजपूर्ण डेटा विश्लेषण के लिए बेहद उपयोगी हैं। उदाहरण के लिए, कोई यूज़र अलग-अलग समय अवधियों पर आयत को ड्रैग कर सकता है ताकि Dash ऐप में संबंधित समरी आँकड़े रियल-टाइम में अपडेट हों। या वे किसी अलग बिंदु-समूह के चयन के लिए वृत्त का आकार बदल सकते हैं और आगे जाँच कर सकते हैं।

हालाँकि ये शक्तिशाली हैं, जटिल वेब अनुप्रयोगों में editable shapes का भारी उपयोग प्रदर्शन पर असर डाल सकता है। फिर भी, सचमुच डायनेमिक और यूज़र-चालित टूल बनाने के लिए ये अपरिहार्य हैं। 

इंटरैक्टिविटी का अन्वेषण आधुनिक डेटा विज़ुअलाइज़ेशन का एक महत्वपूर्ण हिस्सा है—यह विषय Interactive Data Visualization with Plotly in R जैसे कोर्सों में अच्छी तरह से कवर किया गया है, जो अपने Python समकक्ष के कई सिद्धांत साझा करता है।

अन्य लाइब्रेरीज़ के साथ Plotly का एकीकरण

हालाँकि Plotly के बिल्ट-इन shapes बहुमुखी हैं, कभी-कभी आपको अत्यधिक जटिल या कस्टम ज्यामितियाँ बनानी होती हैं। Shapely जैसी विशिष्ट लाइब्रेरीज़ के साथ एकीकरण करके, आप परिष्कृत बहुभुज परिभाषित कर सकते हैं और उन्हें कस्टम Plotly shapes के रूप में अपनी विज़ुअलाइज़ेशन्स में जोड़ सकते हैं।

एडवांस्ड ज्यामितीय shapes के लिए Shapely का उपयोग

Shapely प्लानर ज्यामितीय ऑब्जेक्ट्स के प्रबंधन और विश्लेषण के लिए एक शक्तिशाली Python लाइब्रेरी है। यह कम्प्यूटेशनल ज्योमेट्री के लिए पसंदीदा टूल है, जो अक्सर जियोस्पैशियल विश्लेषण में उपयोग होता है। आप इसका उपयोग, उदाहरण के लिए, दो ओवरलैपिंग वृत्तों के संघ या किसी छेद वाले बहुभुज जैसे जटिल shapes बनाने के लिए कर सकते हैं, और फिर उन्हें Plotly में विज़ुअलाइज़ कर सकते हैं।

यह प्रक्रिया दो मुख्य चरणों में होती है:

  1. Shapely का उपयोग करके जटिल shape परिभाषित करें।
  2. Shapely ऑब्जेक्ट से निर्देशांक निकालें और उन्हें एक SVG पाथ स्ट्रिंग के रूप में फ़ॉर्मेट करें, जिसे Plotly type: 'path' का उपयोग करके रेंडर कर सकता है।

एक SVG पाथ स्ट्रिंग ड्रॉइंग के लिए एक मिनी-लैंग्वेज है। यह M (moveto) से शुरुआती बिंदु सेट करने, L (lineto) से नए बिंदु तक रेखा खींचने, और Z से पाथ को प्रारंभ पर लौटाकर बंद करने जैसे कमांड का उपयोग करती है।

आइए एक कटआउट वाले बहुभुज को बनाना और उसे किसी Plotly फिगर में जोड़ना देखें।

import plotly.graph_objects as go
from shapely.geometry import Polygon

# 1. Create a complex shape using Shapely
# An outer rectangle
outer_coords = [(1, 1), (1, 5), (8, 5), (8, 1)]
# An inner rectangle (this will be the "hole")
inner_coords = [(3, 2), (3, 4), (6, 4), (6, 2)]

# Define the polygon with a hole
polygon_with_hole = Polygon(outer_coords, [inner_coords])

# 2. Extract coordinates and build the SVG path string
# The exterior path
exterior_x, exterior_y = polygon_with_hole.exterior.xy
path = f"M {exterior_x[0]} {exterior_y[0]}"
for x, y in zip(exterior_x[1:], exterior_y[1:]):
    path += f" L {x} {y}"
path += " Z" # Close the exterior path

# The interior path (the hole)
interior_x, interior_y = polygon_with_hole.interiors[0].xy
path += f" M {interior_x[0]} {interior_y[0]}"
for x, y in zip(interior_x[1:], interior_y[1:]):
    path += f" L {x} {y}"
path += " Z" # Close the interior path

# Create a figure
fig = go.Figure()

# Add the complex shape to the figure
fig.add_shape(
    type="path",
    path=path,
    fillcolor="LightSeaGreen",
    opacity=0.7,
    line_color="DarkSlateGray"
)

# You can add data to see how the shape interacts with it
fig.add_trace(go.Scatter(
    x=[2, 7, 4.5], 
    y=[3, 3, 1.5], 
    mode='markers', 
    marker=dict(size=15, color='DarkRed')
))

# Use scaleanchor to ensure the shape's aspect ratio is preserved
fig.update_yaxes(scaleanchor="x", scaleratio=1)
fig.show()

आउटपुट:

Using Shapely for advanced geometric shapes

यह तकनीक जियोस्पैशियल एप्लीकेशन्स—जैसे कस्टम सेल्स टेरिटरीज़ प्लॉट करना—या वैज्ञानिक संदर्भों में, जहाँ आपको अनियमित रुचि-क्षेत्रों को हाईलाइट करना पड़ सकता है, में अमूल्य है। 

यह समझना कि विभिन्न प्रकार के डेटा प्लॉट कैसे बनाए जाते हैं और ऐसे टूल्स से उन्हें कैसे संवर्धित किया जा सकता है, किसी भी डेटा प्रैक्टिशनर के लिए बुनियादी कौशल है। आप इस गाइड में Python में उन्हें कैसे बनाते हैं के बारे में और जान सकते हैं।

स्टाइलिंग और एस्थेटिक कस्टमाइज़ेशन

Plotly shapes का डिफ़ॉल्ट रूप फ़ंक्शनल है, लेकिन पेशेवर और निखरे हुए विज़ुअलाइज़ेशन बनाने के लिए उनके स्टाइल को कस्टमाइज़ करना महत्वपूर्ण है। रंग, अपारदर्शिता और फिल्स का सोच-समझकर उपयोग पठनीयता और सौंदर्य अपील को काफी बढ़ा सकता है।

रंग, अपारदर्शिता, और पैटर्न फिल्स

Plotly आपको shapes की उपस्थिति पर सूक्ष्म-स्तरीय नियंत्रण देता है, जिससे आप उन्हें अपने प्लॉट की रंग योजना और डिज़ाइन भाषा से मेल करा सकते हैं।

रंग और पारदर्शिता पर सटीक नियंत्रण के लिए RGBA (Red, Green, Blue, Alpha) रंग विनिर्देश का उपयोग अत्यधिक अनुशंसित है। a (alpha) चैनल अपारदर्शिता को नियंत्रित करता है, जहाँ 1 का मान पूर्ण अपारदर्शी और 0 का मान पूर्ण पारदर्शी होता है। 

यह नॉन-ऑब्ट्रूसिव हाइलाइट्स बनाने के लिए आवश्यक है, जहाँ shape संदर्भ जोड़ता है बिना नीचे के डेटा को पूरी तरह छिपाए। आप RGBA मानों को इस तरह की स्ट्रिंग के रूप में दे सकते हैं: 'rgba(255, 99, 71, 0.5)'। आइए एक उदाहरण देखें:

import plotly.graph_objects as go
import numpy as np

# Create sample data for styling demonstration
x = np.linspace(0, 10, 100)
y1 = np.sin(x) + np.random.normal(0, 0.1, 100)
y2 = np.cos(x) + np.random.normal(0, 0.1, 100)

fig = go.Figure()
fig.add_trace(go.Scatter(x=x, y=y1, name='Signal 1', line=dict(color='blue')))
fig.add_trace(go.Scatter(x=x, y=y2, name='Signal 2', line=dict(color='red')))

# RGBA Color Technique 1: Graduated opacity for depth
opacity_levels = [0.15, 0.25, 0.35]
colors = ['255,0,0', '0,255,0', '0,0,255']

for i, (opacity, color) in enumerate(zip(opacity_levels, colors)):
    fig.add_shape(
        type="rect",
        x0=i*2.5, x1=(i+1)*2.5,
        y0=-3, y1=3,
        fillcolor=f"rgba({color},{opacity})",
        line=dict(color=f"rgb({color})", width=2),
        layer="below"
    )

# RGBA Technique 2: Color blending for overlapping regions
fig.add_shape(
    type="circle",
    x0=7.5, x1=9.5,
    y0=-1, y1=1,
    fillcolor="rgba(255, 255, 0, 0.4)",  # Semi-transparent yellow
    line=dict(color="orange", width=3),
    layer="below"
)

fig.update_layout(
    title="Advanced RGBA Color Techniques in Plotly Shapes",
    showlegend=True
)
fig.show()

आउटपुट:

Color, opacity, and pattern fills

पैटर्न फिल सिमुलेशन रणनीतियाँ

हालाँकि Plotly मूल रूप से पैटर्न फिल्स का समर्थन नहीं करता, डेटा प्रैक्टिशनर्स रचनात्मक तकनीकों का उपयोग करके जटिल फिल पैटर्न का सिमुलेशन कर सकते हैं। उदाहरण के लिए, हम नीचे दिखाए अनुसार किसी फ़ंक्शन का उपयोग करके प्लॉट में पैटर्न बना सकते हैं:

def create_pattern_fill_simulation(fig, x0, x1, y0, y1, pattern_type='diagonal'):
    """Simulate pattern fills using multiple overlapping shapes"""
    
    if pattern_type == 'diagonal':
        # Create diagonal line pattern
        line_spacing = 0.2
        line_width = 1
        
        # Calculate diagonal lines
        range_x = x1 - x0
        range_y = y1 - y0
        num_lines = int((range_x + range_y) / line_spacing)
        
        for i in range(num_lines):
            offset = i * line_spacing
            
            # Calculate line endpoints for diagonal pattern
            start_x = max(x0, x0 + offset - range_y)
            start_y = max(y0, y1 - offset)
            end_x = min(x1, x0 + offset)
            end_y = min(y1, y1 - offset + range_x)
            
            fig.add_shape(
                type="line",
                x0=start_x, x1=end_x,
                y0=start_y, y1=end_y,
                line=dict(color="rgba(0, 0, 0, 0.3)", width=line_width),
                layer="above"
            )
    
    elif pattern_type == 'crosshatch':
        # Create crosshatch pattern
        spacing = 0.3
        
        # Vertical lines
        x_lines = np.arange(x0, x1, spacing)
        for x_line in x_lines:
            fig.add_shape(
                type="line",
                x0=x_line, x1=x_line,
                y0=y0, y1=y1,
                line=dict(color="rgba(100, 100, 100, 0.4)", width=1),
                layer="above"
            )
        
        # Horizontal lines
        y_lines = np.arange(y0, y1, spacing)
        for y_line in y_lines:
            fig.add_shape(
                type="line",
                x0=x0, x1=x1,
                y0=y_line, y1=y_line,
                line=dict(color="rgba(100, 100, 100, 0.4)", width=1),
                layer="above"
            )
    
    return fig

# Demonstration of pattern fill simulation
pattern_fig = go.Figure()
pattern_fig.add_trace(go.Scatter(x=[1, 2, 3, 4, 5], y=[2, 4, 3, 5, 1], 
                                mode='lines+markers', name='Data'))

# Add base rectangle
pattern_fig.add_shape(
    type="rect",
    x0=1.5, x1=3.5,
    y0=1, y1=5,
    fillcolor="rgba(200, 200, 255, 0.3)",
    line=dict(color="blue", width=2),
    layer="below"
)

# Apply pattern fill simulation
pattern_fig = create_pattern_fill_simulation(pattern_fig, 1.5, 3.5, 1, 5, 'diagonal')
pattern_fig.show()

पैटर्न फिल सिमुलेशन रणनीतियाँ

ग्रेडिएंट प्रभाव सिमुलेशन

ग्रेडिएंट जैसे प्रभाव बनाने के लिए विभिन्न अपारदर्शिताओं वाली कई आकृतियों की रणनीतिक लेयरिंग की आवश्यकता होती है। हम नीचे दिखाए अनुसार, वही रणनीति अपनाकर इसे बना सकते हैं जिसका उपयोग हमने पैटर्न बनाने के लिए किया था:

def create_gradient_effect(fig, x0, x1, y0, y1, start_color, end_color, num_bands=20):
    """Simulate gradient fill using multiple rectangular bands"""
    
    # Parse RGB values from color strings
    def parse_rgb(color_str):
        if color_str.startswith('rgb('):
            values = color_str[4:-1].split(',')
            return [int(v.strip()) for v in values]
        return [0, 0, 0]  # Default to black if parsing fails
    
    start_rgb = parse_rgb(start_color) if isinstance(start_color, str) else start_color
    end_rgb = parse_rgb(end_color) if isinstance(end_color, str) else end_color
    
    band_height = (y1 - y0) / num_bands
    
    for i in range(num_bands):
        # Calculate interpolated color
        ratio = i / (num_bands - 1)
        r = int(start_rgb[0] + (end_rgb[0] - start_rgb[0]) * ratio)
        g = int(start_rgb[1] + (end_rgb[1] - start_rgb[1]) * ratio)
        b = int(start_rgb[2] + (end_rgb[2] - start_rgb[2]) * ratio)
        
        # Calculate band position
        band_y0 = y0 + i * band_height
        band_y1 = band_y0 + band_height
        
        fig.add_shape(
            type="rect",
            x0=x0, x1=x1,
            y0=band_y0, y1=band_y1,
            fillcolor=f"rgba({r}, {g}, {b}, 0.7)",
            line=dict(width=0),  # No border for seamless gradient
            layer="below"
        )
    
    return fig

# Apply gradient effect
gradient_fig = go.Figure()
gradient_fig.add_trace(go.Scatter(x=list(range(10)), 
                                 y=np.random.randn(10).cumsum(),
                                 mode='lines', name='Time Series'))

gradient_fig = create_gradient_effect(
    gradient_fig, 2, 8, -3, 3, 
    [255, 0, 0], [0, 0, 255],  # Red to blue gradient
    num_bands=30
)
gradient_fig.show()

आउटपुट: 

ग्रेडिएंट प्रभाव सिमुलेशन

समस्या निवारण और अनुकूलन

आम तौर पर Plotly में आकृतियाँ जोड़ना सरल होता है, लेकिन जटिल प्लॉट्स में संरेखण या प्रदर्शन संबंधी समस्याएँ आ सकती हैं। इन सामान्य खामियों और उनके समाधान को समझना आपका काफी समय और प्रयास बचा सकता है।

आकृतियों के संरेखण से जुड़ी सामान्य समस्याएँ

सबसे आम चुनौतियों में से एक है आकृतियों को ठीक उसी स्थान पर दिखाना जहाँ आप चाहते हैं। उदाहरण के लिए, पूरी प्लॉट चौड़ाई में फैली एक रेखा छोटी पड़ सकती है, या एक आयत ग्रिड लाइनों के साथ उम्मीद के मुताबिक संरेखित न हो। ये समस्याएँ लगभग हमेशा गलत निर्देशांक संदर्भ के कारण होती हैं।

Plotly आकृतियों को रखने के लिए दो निर्देशांक प्रणालियाँ उपयोग करता है:

  • डेटा निर्देशांक (xref: 'x', yref: 'y'): यह डिफ़ॉल्ट है। आकृति की स्थिति x और y अक्षों के मानों से जुड़ी होती है। उदाहरण के लिए, x0=50 x-अक्ष पर 50 के स्थान पर बिंदु रखता है।
  • पेपर निर्देशांक (xref: 'paper', yref: 'paper'): स्थिति स्वयं प्लॉटिंग क्षेत्र के सापेक्ष होती है, जहाँ 0 शुरुआत (बाएँ/निचला किनारा) और 1 अंत (दायाँ/ऊपरी किनारा) होता है। यह प्रणाली डेटा मानों या अक्ष रेंज से स्वतंत्र होती है।

समस्या: आप y=10 पर पूरी प्लॉट में फैली क्षैतिज रेखा खींचना चाहते हैं। यदि आप इसे डेटा निर्देशांकों में x0 और x1 से परिभाषित करते हैं, तो यह केवल वर्तमान अक्ष रेंज तक फैलेगी। यदि उपयोगकर्ता ज़ूम या पैन करता है, तो रेखा नए किनारों तक नहीं बढ़ेगी।

समाधान: किसी आकृति को प्लॉटिंग क्षेत्र की पूरी चौड़ाई या ऊँचाई में फैलाने के लिए, जिस अक्ष पर फैलाना है उसके लिए 'paper' निर्देशांक का उपयोग करें।

import plotly.graph_objects as go

fig = go.Figure(data=go.Scatter(x=[0, 10], y=[0, 20]))

# Incorrect: Vertical line that might not span the full height if the user zooms out.
# This line is drawn from y=0 to y=20 in DATA units.
fig.add_shape(
    type="line",
    x0=5, y0=0, x1=5, y1=20,
    line=dict(color="Red", width=2, dash="dash"),
    name="Incorrect Line" # Name for legend
)

# Correct: Vertical line that ALWAYS spans the full plot height.
# It is drawn from the bottom edge (0) to the top edge (1) of the PLOT area.
fig.add_shape(
    type="line",
    x0=8, y0=0, x1=8, y1=1,
    yref="paper", # The key to spanning the full height
    line=dict(color="Green", width=3),
    name="Correct Line"
)

fig.update_layout(title_text="Correctly Spanning the Plot Area")
fig.show()

आउटपुट:

हमेशा अपने xref और yref गुणों की दोबारा जाँच करें ताकि ज़ूमिंग और पैनिंग जैसी उपयोगकर्ता अंतःक्रियाओं के दौरान आपकी आकृतियाँ अपेक्षित रूप से व्यवहार करें।

प्रदर्शन संबंधी विचार

यदि आप किसी प्लॉट में कुछ ही आकृतियाँ जोड़ते हैं, तो प्रदर्शन पर प्रभाव नगण्य होता है। लेकिन सैकड़ों या हज़ारों आकृतियाँ जोड़ना रेंडरिंग और इंटरैक्टिविटी को काफ़ी धीमा कर सकता है। प्रत्येक आकृति वेब पेज के DOM में जोड़ा गया एक अलग SVG (Scalable Vector Graphics) तत्व होती है। बड़ी संख्या में DOM तत्व ब्राउज़र पर दबाव डालते हैं।

प्रदर्शन को अनुकूलित करने के लिए ये रणनीतियाँ अपनाएँ:

  • आकृतियों की संख्या सीमित करें: यह सबसे सरल समाधान है। यदि आपको हज़ारों आयताकार क्षेत्रों का चित्रण करना है, तो सोचें कि क्या कोई अलग चार्ट प्रकार, जैसे go.Heatmap, वही जानकारी अधिक कुशलता से एक सिंगल ट्रेस के रूप में दिखा सकता है, न कि हज़ारों shape ऑब्जेक्ट्स के रूप में।
  • bulk जोड़ के लिए update_layout का उपयोग करें: जैसा पहले बताया गया, fig.update_layout(shapes=...) के माध्यम से आकृतियों की सूची जोड़ना लूप में fig.add_shape() कॉल करने से अधिक performant होता है।
  • डेटा के लिए WebGL ट्रेसेज़ पर विचार करें: यद्यपि आकृतियाँ SVG के रूप में रेंडर होती हैं, आप अपने मुख्य डेटा के लिए WebGL-आधारित ट्रेसेज़ (जैसे, go.Scattergl) का उपयोग करके जटिल प्लॉट के समग्र प्रदर्शन में सुधार कर सकते हैं। यह डेटा रेंडरिंग को GPU पर स्थानांतरित करता है, जिससे CPU SVG आकृतियों को अधिक सुगमता से संभाल सकता है। यह तब उपयोगी है जब आपके पास बहुत अधिक डेटा बिंदु और मध्यम संख्या में आकृतियाँ हों।

अधिकांश उपयोग मामलों में, कुंजी यह है कि आप कितने अद्वितीय shape तत्व बना रहे हैं, इस पर सजग रहें। किसी लूप में हज़ारों Plotly आकृतियाँ जोड़ने से पहले, ठहरें और सोचें कि क्या कोई अधिक performant विज़ुअलाइज़ेशन रणनीति मौजूद है।

निष्कर्ष

Plotly आकृतियों में महारत आपके ग्राफ़ों को सरल डेटा प्रस्तुतियों से आगे ले जाकर प्रभावशाली, संदर्भ-समृद्ध कहानियों में बदल देती है। हमने बुनियादी रेखाएँ और आयतें खींचने से लेकर जटिल, इंटरैक्टिव ज्यामितियों की लेयरिंग तक सब देखा। 

इन तकनीकों को अपनाकर, आप अपने दर्शकों का ध्यान सही जगह ले जा सकते हैं, महत्वपूर्ण निष्कर्षों को रेखांकित कर सकते हैं, और अधिक सहज विज़ुअलाइज़ेशन बना सकते हैं जो स्पष्टता और प्रभाव के साथ संप्रेषित करें। 

क्या आप इन कौशलों को लागू करने के लिए तैयार हैं? आज ही और अधिक शक्तिशाली विज़ुअलाइज़ेशन बनाना शुरू करें, Introduction to Data Visualization with Plotly in Python कोर्स को एक्सप्लोर करके और अपने ज्ञान को परखकर।

Plotly आकृतियाँ: सामान्य प्रश्न

Plotly shapes का उपयोग किस लिए किया जाता है?

Plotly आकृतियों का उपयोग ग्राफ़ पर प्रमुख डेटा क्षेत्रों को हाइलाइट करने के लिए रेखाएँ, आयतें और वृत्त जैसी एनोटेशन जोड़ने में किया जाता है।

Plotly में एक से अधिक आकृतियाँ कैसे जोड़ते हैं?

आप fig.update_layout() में shapes एट्रिब्यूट को shape डिक्शनरी की सूची पास करके कई आकृतियाँ कुशलता से जोड़ सकते हैं।

Plotly में वर्टिकल लाइन कैसे खींचते हैं?

आप type='line' का उपयोग करके और yref='paper' गुण सेट करके पूरी प्लॉट ऊँचाई में फैली लंबवत रेखा खींच सकते हैं।

क्या आप Plotly में आकृति को डेटा के पीछे रख सकते हैं?

हाँ, आप किसी आकृति की layer प्रॉपर्टी को 'below' पर सेट करके उसे डेटा ट्रेसेज़ के पीछे रख सकते हैं।

Plotly में केवल एक सबप्लॉट में आकृति कैसे जोड़ते हैं?

आप किसी विशेष सबप्लॉट में आकृति जोड़ सकते हैं, बशर्ते उसकी परिभाषा में xref और yref आर्ग्युमेंट प्रदान किए जाएँ।

लेखक

Rajesh Kumar

मैं एक डेटा साइंस कंटेंट राइटर हूँ। मुझे एआई/एमएल/डीएस विषयों पर सामग्री बनाना पसंद है। मैं नए एआई टूल्स भी खोजता/खोजती हूँ और उनके बारे में लिखता/लिखती हूँ।

विषय