Ipython नोटबुक में एक matplotlib प्लॉट के लिए एक मनमानी लाइन जोड़ना


119

मैं अजगर / matplotlib दोनों के लिए नया हूँ और ipython नोटबुक के माध्यम से इसका उपयोग कर रहा हूँ। मैं एक मौजूदा ग्राफ में कुछ एनोटेशन लाइनों को जोड़ने की कोशिश कर रहा हूं और मैं यह पता नहीं लगा सकता कि किसी ग्राफ पर लाइनों को कैसे प्रस्तुत किया जाए। इसलिए, उदाहरण के लिए, अगर मैं निम्नलिखित की साजिश रचूं:

import numpy as np
np.random.seed(5)
x = arange(1, 101)
y = 20 + 3 * x + np.random.normal(0, 60, 100)
p =  plot(x, y, "o")

मुझे निम्नलिखित ग्राफ मिलता है:

सुंदर तितर बितर साजिश

तो मैं (70,100) से (70,250) तक एक ऊर्ध्वाधर रेखा कैसे जोड़ूंगा? (70,100) से (90,200) तक एक विकर्ण रेखा के बारे में क्या?

मैंने कुछ चीजों की कोशिश की है Line2D()जिसके परिणामस्वरूप मेरे हिस्से में भ्रम के अलावा कुछ भी नहीं है। में Rमैं बस सेगमेंट () फ़ंक्शन का उपयोग करूंगा जो लाइन सेगमेंट को जोड़ देगा। में एक बराबर है matplotlib?

जवाबों:


185

आप plotसंबंधित डेटा (खंडों की सीमा) के साथ कमांड को फीड करके अपनी इच्छित लाइनों को सीधे प्लॉट कर सकते हैं :

plot([x1, x2], [y1, y2], color='k', linestyle='-', linewidth=2)

(बेशक आप रंग, लाइन की चौड़ाई, रेखा शैली, आदि का चयन कर सकते हैं)

अपने उदाहरण से:

import numpy as np
import matplotlib.pyplot as plt

np.random.seed(5)
x = np.arange(1, 101)
y = 20 + 3 * x + np.random.normal(0, 60, 100)
plt.plot(x, y, "o")


# draw vertical line from (70,100) to (70, 250)
plt.plot([70, 70], [100, 250], 'k-', lw=2)

# draw diagonal line from (70, 90) to (90, 200)
plt.plot([70, 90], [90, 200], 'k-')

plt.show()

नया चार्ट


उत्कृष्ट और पूर्ण चित्रण के साथ शानदार उत्तर! बहुत बहुत शुक्रिया!
JD लॉन्ग

2
मामूली सुधार, ऊपर दिए गए कोड को पढ़ना चाहिए x = np.arange(1, 101)
WP McNeill

यह एक रेखा नहीं, बल्कि केवल एक खंड खींचेगा। प्रश्न यह है कि दो दिए गए बिंदुओं को फेंकने वाली रेखा को कैसे खींचा जाए।
एलेक्सी

6
@ रमनो आप "_" से शुरू होने वाले लेबल तर्क को जोड़कर किंवदंती में शामिल किए जाने वाले सेगमेंट से बच सकते हैं। Ex:plt.plot([70, 70], [100, 250], 'k-', lw=2, label="_not in legend")
gcalmettes

1
यह तथ्य कि 90दोनों के रूप में उपयोग किया जाता है x2और y1बहुत अधिक अस्पष्टता की ओर जाता है। इसे देखने वाले किसी भी व्यक्ति के लिए, ध्यान दें कि [70, 90]स्थान पर एक भी बिंदु नहीं है x1,y1। संदर्भ के लिए, यहां मूल्यों के अर्थ दिए गए हैं:[x1: 70, x2: 90], [y1: 90, y2: 200]
pookie

61

नए लोगों के लिए बहुत देर नहीं हुई है ।

plt.axvline(x, color='r')

यह ymin और ymax का उपयोग करने के साथ-साथ y की सीमा भी लेता है।


1
Axhline और axvline के न्यूनतम / अधिकतम पैरामीटर 0 और 1 के बीच स्केलर मान हैं जो प्लॉट के किनारे के संदर्भ में प्लॉट लाइनें हैं। हालांकि एक अच्छा उपकरण, यह संभवतः लेखक की समस्या बयान का सबसे अच्छा समाधान नहीं है जो एनोटेशन लाइनों को आरेखित करता है।
बाइनरीसबस्ट्रेट

3
यह पृष्ठभूमि में एक एनोटेशन लाइन जोड़ने के लिए एकदम सही है जो पूरे ग्राफ को फैलाता है। यदि मैं x = 1 पर एक ऊर्ध्वाधर रेखा खींचने के लिए ऊपर दिए गए चुने हुए समाधान का उपयोग करता हूं, तो मुझे न्यूनतम और अधिकतम y निर्दिष्ट करना होगा, और फिर प्लॉट स्वचालित रूप से एक बफर के साथ आकार बदलता है, इसलिए लाइन पूरे प्लॉट में खिंचाव नहीं करती है, और यह एक परेशानी है। यह अधिक सुरुचिपूर्ण है और भूखंड का आकार परिवर्तन नहीं करता है।
बोनी

40

का उपयोग कर vlines:

import numpy as np
np.random.seed(5)
x = arange(1, 101)
y = 20 + 3 * x + np.random.normal(0, 60, 100)
p =  plot(x, y, "o")
vlines(70,100,250)

मूल कॉल हस्ताक्षर हैं:

vlines(x, ymin, ymax)
hlines(y, xmin, xmax)

2
वह तो बहुत ही बढ़िया है। मैंने vline()या hline()कार्यों को नहीं देखा था । विकर्ण लाइनों के बारे में क्या? मैंने विकर्ण को जोड़ने के लिए प्रश्न संपादित किया है कि अब आपने मुझे h & v लाइनें दिखाई हैं।
JD लॉन्ग


धन्यवाद, यह बहुत उपयोगी है
एलेक्स

6

Matplolib अब 'एनोटेशन लाइनों' के लिए अनुमति देता है क्योंकि ओपी मांग रहा था। annotate()समारोह को जोड़ने पथ के कई रूपों और एक बिना सिर और tailess तीर, यानी, एक सरल रेखा, उनमें से एक है की अनुमति देता है।

ax.annotate("",
            xy=(0.2, 0.2), xycoords='data',
            xytext=(0.8, 0.8), textcoords='data',
            arrowprops=dict(arrowstyle="-",
                      connectionstyle="arc3, rad=0"),
            )

में प्रलेखन यह आपको पहले तर्क के रूप में एक खाली स्ट्रिंग के साथ ही एक तीर आकर्षित कर सकते हैं कहते हैं।

ओपी के उदाहरण से:

%matplotlib notebook
import numpy as np
import matplotlib.pyplot as plt

np.random.seed(5)
x = np.arange(1, 101)
y = 20 + 3 * x + np.random.normal(0, 60, 100)
plt.plot(x, y, "o")


# draw vertical line from (70,100) to (70, 250)
plt.annotate("",
              xy=(70, 100), xycoords='data',
              xytext=(70, 250), textcoords='data',
              arrowprops=dict(arrowstyle="-",
                              connectionstyle="arc3,rad=0."), 
              )

# draw diagonal line from (70, 90) to (90, 200)
plt.annotate("",
              xy=(70, 90), xycoords='data',
              xytext=(90, 200), textcoords='data',
              arrowprops=dict(arrowstyle="-",
                              connectionstyle="arc3,rad=0."), 
              )

plt.show()

उदाहरण इनलाइन छवि

जिस तरह से गॉकेटमेट के उत्तर में दृष्टिकोण है, आप रंग, रेखा की चौड़ाई, रेखा शैली, आदि चुन सकते हैं।

यहां कोड के एक हिस्से में परिवर्तन किया गया है जो दो उदाहरण लाइनों में से एक को लाल, व्यापक और 100% अपारदर्शी बना देगा।

# draw vertical line from (70,100) to (70, 250)
plt.annotate("",
              xy=(70, 100), xycoords='data',
              xytext=(70, 250), textcoords='data',
              arrowprops=dict(arrowstyle="-",
                              edgecolor = "red",
                              linewidth=5,
                              alpha=0.65,
                              connectionstyle="arc3,rad=0."), 
              )

आप एडजस्ट करने वाली लाइन से वक्र को एडजस्ट करके भी जोड़ सकते हैं connectionstyle


1
यह वही है जो मैंने समाप्त किया। मैं भूखंड की सीमाओं के बाहर जाने वाली एक रेखा खींचना चाहता था, जो .plot()नहीं कर सकता।
निक एस

5

गाली देने के बजाय plot या annotate, जो कई लाइनों के लिए अक्षम होगा, आप इसका उपयोग कर सकते हैं matplotlib.collections.LineCollection:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.collections import LineCollection

np.random.seed(5)
x = np.arange(1, 101)
y = 20 + 3 * x + np.random.normal(0, 60, 100)
plt.plot(x, y, "o")

# Takes list of lines, where each line is a sequence of coordinates
l1 = [(70, 100), (70, 250)]
l2 = [(70, 90), (90, 200)]
lc = LineCollection([l1, l2], color=["k","blue"], lw=2)

plt.gca().add_collection(lc)

plt.show()

दो लाइनों के साथ चित्रा LineCollection के माध्यम से साजिश रची

यह लाइनों की एक सूची लेता है [l1, l2, ...], जहां प्रत्येक पंक्ति N निर्देशांक ( N) का एक क्रम है दो से अधिक हो सकता है)।

मानक फ़ॉर्मेटिंग कीवर्ड उपलब्ध हैं, जो या तो एकल मान को स्वीकार करते हैं, जिस स्थिति में मूल्य हर पंक्ति पर लागू होता है, या एम का एक क्रम होता है values, जिस स्थिति के लिए मूल्य i वीं पंक्ति के है values[i % M]

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.