python - Matplotlib 2 सबप्लॉट्स, 1 कलरबार




subplot colorbar (5)

आप figure.colorbar() सूची के साथ figure.colorbar() के ax पैरामीटर का उपयोग करके जो किंगटन के कोड को सरल बना सकते हैं। दस्तावेज़ीकरण से :

कुल्हाड़ी

कोई नहीं | अभिभावक धुरी ऑब्जेक्ट्स (जिसमें से) एक नई रंग पट्टी अक्ष के लिए स्थान चोरी हो जाएगा। यदि अक्षों की एक सूची दी जाती है तो वे सभी रंगीन अक्षों के लिए जगह बनाने के लिए आकार बदल जाएंगे।

import numpy as np
import matplotlib.pyplot as plt

fig, axes = plt.subplots(nrows=2, ncols=2)
for ax in axes.flat:
    im = ax.imshow(np.random.random((10,10)), vmin=0, vmax=1)

fig.colorbar(im, ax=axes.ravel().tolist())

plt.show()

मैंने पूरी तरह से बहुत लंबा शोध किया है कि एक ही वाई-अक्ष को मैटलप्लिब में दो के बीच साझा एक रंगीन रंग के साथ साझा करने के लिए दो सबप्लॉट कैसे प्राप्त करें।

क्या हो रहा था कि जब मैंने या तो subplot1 या subplot2 subplot1 colorbar() फ़ंक्शन कहा था, तो यह प्लॉट को subplot2 करेगा जैसे कि subplot2 प्लस प्लॉट 'सबप्लॉट' बाउंडिंग बॉक्स के अंदर फिट होगा, जिससे दोनों तरफ-साइड प्लॉट होंगे दो बहुत अलग आकार होने के लिए।

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

मेरा कोड यहाँ है:

from __future__ import division
import matplotlib.pyplot as plt
import numpy as np
from matplotlib import patches
from matplotlib.ticker import NullFormatter

# SIS Functions
TE = 1 # Einstein radius
g1 = lambda x,y: (TE/2) * (y**2-x**2)/((x**2+y**2)**(3/2)) 
g2 = lambda x,y: -1*TE*x*y / ((x**2+y**2)**(3/2))
kappa = lambda x,y: TE / (2*np.sqrt(x**2+y**2))

coords = np.linspace(-2,2,400)
X,Y = np.meshgrid(coords,coords)
g1out = g1(X,Y)
g2out = g2(X,Y)
kappaout = kappa(X,Y)
for i in range(len(coords)):
    for j in range(len(coords)):
        if np.sqrt(coords[i]**2+coords[j]**2) <= TE:
            g1out[i][j]=0
            g2out[i][j]=0

fig = plt.figure()
fig.subplots_adjust(wspace=0,hspace=0)

# subplot number 1
ax1 = fig.add_subplot(1,2,1,aspect='equal',xlim=[-2,2],ylim=[-2,2])
plt.title(r"$\gamma_{1}$",fontsize="18")
plt.xlabel(r"x ($\theta_{E}$)",fontsize="15")
plt.ylabel(r"y ($\theta_{E}$)",rotation='horizontal',fontsize="15")
plt.xticks([-2.0,-1.5,-1.0,-0.5,0,0.5,1.0,1.5])
plt.xticks([-2.0,-1.5,-1.0,-0.5,0,0.5,1.0,1.5])
plt.imshow(g1out,extent=(-2,2,-2,2))
plt.axhline(y=0,linewidth=2,color='k',linestyle="--")
plt.axvline(x=0,linewidth=2,color='k',linestyle="--")
e1 = patches.Ellipse((0,0),2,2,color='white')
ax1.add_patch(e1)

# subplot number 2
ax2 = fig.add_subplot(1,2,2,sharey=ax1,xlim=[-2,2],ylim=[-2,2])
plt.title(r"$\gamma_{2}$",fontsize="18")
plt.xlabel(r"x ($\theta_{E}$)",fontsize="15")
ax2.yaxis.set_major_formatter( NullFormatter() )
plt.axhline(y=0,linewidth=2,color='k',linestyle="--")
plt.axvline(x=0,linewidth=2,color='k',linestyle="--")
plt.imshow(g2out,extent=(-2,2,-2,2))
e2 = patches.Ellipse((0,0),2,2,color='white')
ax2.add_patch(e2)

# subplot for colorbar
ax3 = fig.add_subplot(1,1,1)
ax3.axis('off')
cbar = plt.colorbar(ax=ax2)

plt.show()

इस समाधान के लिए axes स्थानों या colorbar आकार के मैन्युअल tweaking की आवश्यकता नहीं है, बहु पंक्ति और एकल पंक्ति लेआउट के साथ काम करता है, और tight_layout() साथ काम करता है। यह matplotlib के एक्सिसग्रिड टूलबॉक्स से ImageGrid का उपयोग कर गैलरी उदाहरण से अनुकूलित किया गया है।

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import ImageGrid

# Set up figure and image grid
fig = plt.figure(figsize=(9.75, 3))

grid = ImageGrid(fig, 111,          # as in plt.subplot(111)
                 nrows_ncols=(1,3),
                 axes_pad=0.15,
                 share_all=True,
                 cbar_location="right",
                 cbar_mode="single",
                 cbar_size="7%",
                 cbar_pad=0.15,
                 )

# Add data to image grid
for ax in grid:
    im = ax.imshow(np.random.random((10,10)), vmin=0, vmax=1)

# Colorbar
ax.cax.colorbar(im)
ax.cax.toggle_label(True)

#plt.tight_layout()    # Works, but may still require rect paramater to keep colorbar labels visible
plt.show()


जैसा कि अन्य उत्तरों में बताया गया है, विचार आमतौर पर रंगीन के लिए अक्षरों को परिभाषित करने के लिए होता है। ऐसा करने के कई तरीके हैं; जिसे अभी तक उल्लेख नहीं किया गया है, वह plt.subplots() साथ subplot निर्माण पर सीधे plt.subplots() अक्ष निर्दिष्ट करना होगा। इसका फायदा यह है कि अक्ष की स्थिति को मैन्युअल रूप से सेट करने की आवश्यकता नहीं होती है और स्वचालित पहलू वाले सभी मामलों में रंग पट्टी सबप्लॉट्स की तरह ही ऊंचाई होगी। यहां तक ​​कि कई मामलों में जहां छवियों का उपयोग किया जाता है, परिणाम नीचे दिखाए गए अनुसार संतुष्ट होंगे।

plt.subplots() का उपयोग करते समय, gridspec_kw तर्क का उपयोग अन्य अक्षों की तुलना में gridspec_kw अक्ष को बहुत छोटा बनाने की अनुमति देता है।

fig, (ax, ax2, cax) = plt.subplots(ncols=3,figsize=(5.5,3), 
                  gridspec_kw={"width_ratios":[1,1, 0.05]})

उदाहरण:

import matplotlib.pyplot as plt
import numpy as np; np.random.seed(1)

fig, (ax, ax2, cax) = plt.subplots(ncols=3,figsize=(5.5,3), 
                  gridspec_kw={"width_ratios":[1,1, 0.05]})
fig.subplots_adjust(wspace=0.3)
im  = ax.imshow(np.random.rand(11,8), vmin=0, vmax=1)
im2 = ax2.imshow(np.random.rand(11,8), vmin=0, vmax=1)
ax.set_ylabel("y label")

fig.colorbar(im, cax=cax)

plt.show()

यह अच्छी तरह से काम करता है, यदि भूखंडों के पहलू को स्वत: संसाधित किया गया है या छवियों को चौड़ाई की दिशा में उनके पहलू के कारण संकुचित किया गया है (जैसा कि उपरोक्त में है)। यदि, हालांकि, छवियां अधिक व्यापक हैं, तो परिणाम निम्नानुसार दिखाई देगा, जो अवांछित हो सकता है।

सबप्लॉट ऊंचाई पर mpl_toolkits.axes_grid1.inset_locator.InsetPosition ऊंचाई को ठीक करने का एक समाधान mpl_toolkits.axes_grid1.inset_locator.InsetPosition का उपयोग छवि सबप्लॉट अक्षों के सापेक्ष mpl_toolkits.axes_grid1.inset_locator.InsetPosition अक्ष सेट करने के लिए होगा।

import matplotlib.pyplot as plt
import numpy as np; np.random.seed(1)
from mpl_toolkits.axes_grid1.inset_locator import InsetPosition

fig, (ax, ax2, cax) = plt.subplots(ncols=3,figsize=(7,3), 
                  gridspec_kw={"width_ratios":[1,1, 0.05]})
fig.subplots_adjust(wspace=0.3)
im  = ax.imshow(np.random.rand(11,16), vmin=0, vmax=1)
im2 = ax2.imshow(np.random.rand(11,16), vmin=0, vmax=1)
ax.set_ylabel("y label")

ip = InsetPosition(ax2, [1.05,0,0.05,1]) 
cax.set_axes_locator(ip)

fig.colorbar(im, cax=cax, ax=[ax,ax2])

plt.show()


बस रंगीन को अपनी धुरी में रखें और इसके लिए जगह बनाने के लिए subplots_adjust का उपयोग करें।

एक त्वरित उदाहरण के रूप में:

import numpy as np
import matplotlib.pyplot as plt

fig, axes = plt.subplots(nrows=2, ncols=2)
for ax in axes.flat:
    im = ax.imshow(np.random.random((10,10)), vmin=0, vmax=1)

fig.subplots_adjust(right=0.8)
cbar_ax = fig.add_axes([0.85, 0.15, 0.05, 0.7])
fig.colorbar(im, cax=cbar_ax)

plt.show()


Abevieiramota द्वारा axes की एक सूची का उपयोग करने का समाधान बहुत अच्छी तरह से काम करता है जब तक आप टिप्पणियों में इंगित करते हुए छवियों की केवल एक पंक्ति का उपयोग नहीं करते हैं। figsize लिए एक उचित पहलू अनुपात का उपयोग करने में मदद करता है, लेकिन अभी भी सही से दूर है। उदाहरण के लिए:

import numpy as np
import matplotlib.pyplot as plt

fig, axes = plt.subplots(nrows=1, ncols=3, figsize=(9.75, 3))
for ax in axes.flat:
    im = ax.imshow(np.random.random((10,10)), vmin=0, vmax=1)

fig.colorbar(im, ax=axes.ravel().tolist())

plt.show()

कलरबार फ़ंक्शन shrink पैरामीटर प्रदान करता है जो रंगीन अक्ष के आकार के लिए एक स्केलिंग कारक है। इसके लिए कुछ मैन्युअल परीक्षण और त्रुटि की आवश्यकता होती है। उदाहरण के लिए:

fig.colorbar(im, ax=axes.ravel().tolist(), shrink=0.75)





colorbar