দ্বিগুণ () এর সাথে গৌণ অক্ষ: কীভাবে কিংবদন্তিতে যুক্ত হবেন?


288

আমার দুটি ওয়াই-এক্স দিয়ে একটি প্লট ব্যবহার করছে twinx()। আমি লাইনগুলিতে লেবেলও দিই এবং সেগুলি দিয়ে দেখাতে চাই legend(), তবে আমি কেবলমাত্র একটি অক্ষের লেবেলগুলি কিংবদন্তীতে পেয়েছি:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib import rc
rc('mathtext', default='regular')

fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(time, Swdown, '-', label = 'Swdown')
ax.plot(time, Rn, '-', label = 'Rn')
ax2 = ax.twinx()
ax2.plot(time, temp, '-r', label = 'temp')
ax.legend(loc=0)
ax.grid()
ax.set_xlabel("Time (h)")
ax.set_ylabel(r"Radiation ($MJ\,m^{-2}\,d^{-1}$)")
ax2.set_ylabel(r"Temperature ($^\circ$C)")
ax2.set_ylim(0, 35)
ax.set_ylim(-20,100)
plt.show()

সুতরাং আমি কেবল কিংবদন্তিতে প্রথম অক্ষের লেবেলগুলি পাই এবং দ্বিতীয় অক্ষের 'টেম্প' লেবেলটি পাই না। আমি কীভাবে এই তৃতীয় লেবেলটি কিংবদন্তিতে যুক্ত করতে পারি?

এখানে চিত্র বর্ণনা লিখুন


4
[ যে কোনও প্রোডাক্ট কোডের নিকটবর্তী স্থানে কোথাও এটি করবেন না ] যখন আমার একমাত্র লক্ষ্য অ্যাপ্রোপিয়েট কিংবদন্তি এএসএপি দিয়ে একটি সুন্দর প্লট তৈরি করা axহয় তখন আমি যে স্টাইলটি ব্যবহার করি তার সাথে খালি অ্যারে প্লট করার একটি কুৎসিত হ্যাক ব্যবহার করি ax2: ইন আপনার কেস ax.plot([], [], '-r', label = 'temp'),। এটি সঠিকভাবে করার চেয়ে অনেক দ্রুত এবং সহজ ...
নিয়নস্টাইন

উত্তর:


370

লাইনটি যুক্ত করে আপনি সহজেই দ্বিতীয় কিংবদন্তি যুক্ত করতে পারেন:

ax2.legend(loc=0)

আপনি এটি পাবেন:

এখানে চিত্র বর্ণনা লিখুন

তবে আপনি যদি একটি লেজেন্ডে সমস্ত লেবেল চান তবে আপনার এমন কিছু করা উচিত:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib import rc
rc('mathtext', default='regular')

time = np.arange(10)
temp = np.random.random(10)*30
Swdown = np.random.random(10)*100-10
Rn = np.random.random(10)*100-10

fig = plt.figure()
ax = fig.add_subplot(111)

lns1 = ax.plot(time, Swdown, '-', label = 'Swdown')
lns2 = ax.plot(time, Rn, '-', label = 'Rn')
ax2 = ax.twinx()
lns3 = ax2.plot(time, temp, '-r', label = 'temp')

# added these three lines
lns = lns1+lns2+lns3
labs = [l.get_label() for l in lns]
ax.legend(lns, labs, loc=0)

ax.grid()
ax.set_xlabel("Time (h)")
ax.set_ylabel(r"Radiation ($MJ\,m^{-2}\,d^{-1}$)")
ax2.set_ylabel(r"Temperature ($^\circ$C)")
ax2.set_ylim(0, 35)
ax.set_ylim(-20,100)
plt.show()

যা আপনাকে এটি দেবে:

এখানে চিত্র বর্ণনা লিখুন


2
এটি errorbarপ্লটের সাথে ব্যর্থ হয় । সমাধানের জন্য যা তাদের সঠিকভাবে পরিচালনা করে, নীচে দেখুন: stackoverflow.com/a/10129461/1319447
ডেভিড

1
আমার ক্ষেত্রে যেমন দুটি .gendend (লোক = 0) নির্দিষ্ট করেছি, সেখানে দুটি ওভারল্যাপিং কিংবদন্তীগুলি রোধ করতে আপনার কিংবদন্তির অবস্থান মানের জন্য দুটি পৃথক মান নির্দিষ্ট করা উচিত (0 ব্যতীত অন্য দুটি)। দেখুন: matplotlib.org/api/legnd_api.html
রোল্ট

একাধিক লাইন সহ কিছু সাবপ্লোটে একটি লাইন যুক্ত করতে আমার কিছুটা সমস্যা হয়েছিল ax1। এই ক্ষেত্রে ব্যবহার করুন lns1=ax1.linesএবং তারপরে lns2এই তালিকায় যুক্ত করুন।
লিটল ববি টেবিলগুলি

বিভিন্ন দ্বারা ব্যবহৃত মান locAre ব্যাখ্যা এখানে
Dror

1
আরও স্বয়ংক্রিয় উপায়ে নীচের উত্তরটি দেখুন (ম্যাটপ্ল্লোব> = ২.১ সহ): স্ট্যাকওভারফ্লো.
জোরিস

183

আমি নিশ্চিত না যে এই কার্যকারিতাটি নতুন কিনা, তবে আপনি নিজেরাই লাইন এবং লেবেলগুলি ট্র্যাক করে রাখার পরিবর্তে get_legnd_handles_labels () পদ্ধতিটি ব্যবহার করতে পারেন:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib import rc
rc('mathtext', default='regular')

pi = np.pi

# fake data
time = np.linspace (0, 25, 50)
temp = 50 / np.sqrt (2 * pi * 3**2) \
        * np.exp (-((time - 13)**2 / (3**2))**2) + 15
Swdown = 400 / np.sqrt (2 * pi * 3**2) * np.exp (-((time - 13)**2 / (3**2))**2)
Rn = Swdown - 10

fig = plt.figure()
ax = fig.add_subplot(111)

ax.plot(time, Swdown, '-', label = 'Swdown')
ax.plot(time, Rn, '-', label = 'Rn')
ax2 = ax.twinx()
ax2.plot(time, temp, '-r', label = 'temp')

# ask matplotlib for the plotted objects and their labels
lines, labels = ax.get_legend_handles_labels()
lines2, labels2 = ax2.get_legend_handles_labels()
ax2.legend(lines + lines2, labels + labels2, loc=0)

ax.grid()
ax.set_xlabel("Time (h)")
ax.set_ylabel(r"Radiation ($MJ\,m^{-2}\,d^{-1}$)")
ax2.set_ylabel(r"Temperature ($^\circ$C)")
ax2.set_ylim(0, 35)
ax.set_ylim(-20,100)
plt.show()

1
এটিই একমাত্র সমাধান যা অক্ষগুলি পরিচালনা করতে পারে যেখানে কিংবদন্তীদের সাথে প্লটগুলি ওভারল্যাপ হয় (শেষ অক্ষগুলি হ'ল কিংবদন্তীদের প্লট করা উচিত)
আমেলিও ওয়াজকেজ-রেইনা

5
এই সমাধানটি errorbarপ্লটগুলির সাথেও কাজ করে , যখন স্বীকৃত একটি ব্যর্থ হয় (একটি লাইন এবং এর ত্রুটি বারগুলি আলাদাভাবে প্রদর্শন করা হয়, এবং এর কোনওটিই সঠিক লেবেলযুক্ত নয়)। আরও, এটি সহজ।
ডেভিড

সামান্য ক্যাচ: আপনি যদি লেবেলটি ওভাররাইট করতে চান তবে এটি কাজ করে না ax2এবং এটির শুরু থেকে কোনও সেট নেই
সিপ্রিয়ান টোমাইগা

মন্তব্য: ক্লাসিক প্লটগুলির জন্য, আপনাকে লেবেল যুক্তি নির্দিষ্ট করার দরকার নেই। তবে অন্যদের জন্য যেমন, বার আপনার প্রয়োজন।
বেলকা

এটি আপনাকে আরও কত সহজ করে তোলে যদি আপনি জানেন না যে কয়টি লাইন প্লট করা হচ্ছে।
ভেগার্ড জেরভেল

77

ম্যাটপ্ল্লোলিব সংস্করণ ২.১ এর পরে, আপনি কোনও চিত্র কিংবদন্তি ব্যবহার করতে পারেন । এর পরিবর্তে ax.legend(), যা অক্ষগুলি থেকে হ্যান্ডলগুলি সহ একটি কিংবদন্তি তৈরি করে ax, কেউ চিত্রের কিংবদন্তি তৈরি করতে পারে

fig.legnd (লোক = "উপরের ডান")

যা চিত্রের সমস্ত সাবপ্লট থেকে সমস্ত হ্যান্ডেল সংগ্রহ করবে। যেহেতু এটি চিত্রের কিংবদন্তি, তাই এটি চিত্রের কোণায় স্থাপন করা হবে এবং locযুক্তিটি চিত্রটির সাথে সম্পর্কিত।

import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(0,10)
y = np.linspace(0,10)
z = np.sin(x/3)**2*98

fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(x,y, '-', label = 'Quantity 1')

ax2 = ax.twinx()
ax2.plot(x,z, '-r', label = 'Quantity 2')
fig.legend(loc="upper right")

ax.set_xlabel("x [units]")
ax.set_ylabel(r"Quantity 1")
ax2.set_ylabel(r"Quantity 2")

plt.show()

এখানে চিত্র বর্ণনা লিখুন

কিংবদন্তিটি অক্ষগুলিতে ফিরিয়ে দেওয়ার জন্য, একটি সরবরাহ করতে হবে a bbox_to_anchorএবং a bbox_transform। আধুনিক হবে অক্ষ অক্ষ কিংবদন্তি রক্ষিত উচিত রুপান্তর। সাবেক প্রান্ত দ্বারা সংজ্ঞায়িত স্থানাঙ্ক হতে পারে locঅক্ষ স্থানাঙ্ক দেওয়া।

fig.legend(loc="upper right", bbox_to_anchor=(1,1), bbox_transform=ax.transAxes)

এখানে চিত্র বর্ণনা লিখুন


সুতরাং, ইতিমধ্যে সংস্করণ 2.1 প্রকাশিত? তবে অ্যানাকোন্ডা 3-তে, আমি conda upgrade matplotlibকোনও নতুন সংস্করণ খুঁজে পাওয়ার চেষ্টা করিনি , আমি এখনও v.2.0.2 ব্যবহার করছি
স্টিফুলিশ

1
এটি শেষ ফলাফল অর্জনের একটি ক্লিনার উপায়।
গৌতম

1
সুন্দর এবং
অজগর

1
আপনার অনেক সাবপ্লট থাকলে এটি কাজ করবে বলে মনে হয় না। এটি সমস্ত সাবপ্লটগুলির জন্য একটি একক কিংবদন্তি যুক্ত করে। প্রতিটি উপ-প্লটের জন্য একটির জন্য সাধারণত একটি কিংবদন্তি প্রয়োজন, প্রতিটি কিংবদন্তিতে প্রাথমিক এবং মাধ্যমিক উভয় অক্ষগুলিতে সিরিজ যুক্ত।
সানচো.এস পুনরায় ইনস্টল করুন মনিকাসেলিও

@ সানচো সঠিক, এই উত্তরের তৃতীয় বাক্যে যা লেখা আছে, "... যা চিত্রের সমস্ত সাবপ্লট থেকে সমস্ত হ্যান্ডেল সংগ্রহ করবে।"
ImportanceOfBeingErnest

38

কুড়ালিতে লাইন যুক্ত করে আপনি যা চান তা সহজেই পেতে পারেন:

ax.plot([], [], '-r', label = 'temp')

অথবা

ax.plot(np.nan, '-r', label = 'temp')

এটি কুঠারটির কিংবদন্তিতে একটি লেবেল যুক্ত করা ছাড়া আর কিছুই প্লট করবে না।

আমি মনে করি এটি অনেক সহজ উপায়। উপরের মতো হাতে ফিক্সিং করা খুব সহজ হবে যখন আপনার দ্বিতীয় অক্ষগুলিতে কেবল কয়েকটি লাইন থাকে তখন স্বয়ংক্রিয়ভাবে লাইনগুলি ট্র্যাক করা প্রয়োজন হয় না। যাইহোক, এটি আপনার প্রয়োজনের উপর নির্ভর করে।

পুরো কোডটি নীচের মতো:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib import rc
rc('mathtext', default='regular')

time = np.arange(22.)
temp = 20*np.random.rand(22)
Swdown = 10*np.random.randn(22)+40
Rn = 40*np.random.rand(22)

fig = plt.figure()
ax = fig.add_subplot(111)
ax2 = ax.twinx()

#---------- look at below -----------

ax.plot(time, Swdown, '-', label = 'Swdown')
ax.plot(time, Rn, '-', label = 'Rn')

ax2.plot(time, temp, '-r')  # The true line in ax2
ax.plot(np.nan, '-r', label = 'temp')  # Make an agent in ax

ax.legend(loc=0)

#---------------done-----------------

ax.grid()
ax.set_xlabel("Time (h)")
ax.set_ylabel(r"Radiation ($MJ\,m^{-2}\,d^{-1}$)")
ax2.set_ylabel(r"Temperature ($^\circ$C)")
ax2.set_ylim(0, 35)
ax.set_ylim(-20,100)
plt.show()

প্লটটি নীচে রয়েছে:

এখানে চিত্র বর্ণনা লিখুন


আপডেট: আরও ভাল সংস্করণ যুক্ত করুন:

ax.plot(np.nan, '-r', label = 'temp')

plot(0, 0)অক্ষ পরিসর পরিবর্তন করতে পারে এমন এটি কিছু করবে না ।


বিক্ষিপ্ত জন্য একটি অতিরিক্ত উদাহরণ

ax.scatter([], [], s=100, label = 'temp')  # Make an agent in ax
ax2.scatter(time, temp, s=10)  # The true scatter in ax2

ax.legend(loc=1, framealpha=1)

3
আমি এই পছন্দ। এটি সিস্টেমকে "কৌশল" দেয়ায় এটির মতো কুৎসিত, তবে এটি কার্যকর করা সহজ।
ড্যানিয়েল পাওয়ার

এটি বাস্তবায়নের জন্য সত্যই সহজ। তবে স্ক্যাটারের সাথে এটি ব্যবহার করার সময়, কিংবদন্তিতে ফলাফলযুক্ত স্ক্যাটার আকারটি কেবলমাত্র একটি ক্ষুদ্র বিন্দু।
greeeeeeen

@ গ্রিআইইন তারপরে স্ক্রেটার প্লট তৈরি করার সময় আপনাকে কেবল চিহ্নিতকারী আকারটি নির্দিষ্ট করতে হবে :-)
সিআরটিস মেজর

@ সির্তিসমজর আমি অবশ্যই চেষ্টা করেছি। তবে এটি কিংবদন্তিতে মার্কারের আকার পরিবর্তন করেনি।
গ্রিণীউইন

@ গ্রেইউইন আপনি কি এজেন্ট স্ক্রেটারের মার্কার আকার পরিবর্তন করেছেন? আমার পোস্ট দেখুন, আমি উদাহরণ কোড একটি স্নিপেট যোগ।
Syrtis মেজর

7

আপনার প্রয়োজন অনুসারে একটি দ্রুত হ্যাক ..

বাক্সের ফ্রেমটি খুলে নিন এবং ম্যানুয়ালি দুটি কিংবদন্তি একে অপরের পাশে অবস্থিত করুন। এটার মতো কিছু..

ax1.legend(loc = (.75,.1), frameon = False)
ax2.legend( loc = (.75, .05), frameon = False)

যেখানে লোকাল টিপলটি বাম থেকে ডান এবং নীচে থেকে শীর্ষে শতাংশ যা চার্টে অবস্থানটি উপস্থাপন করে।


5

আমি নীচের একটি অফিসিয়াল ম্যাটপ্ল্লিটব উদাহরণ পেয়েছি যা একাধিক ওয়াই-অক্ষ এবং একক কিংবদন্তীতে সমস্ত ভিন্ন লেবেল প্রদর্শন করতে হোস্ট_সপপ্লট ব্যবহার করে। কোন workaround প্রয়োজন। আমি এখনও অবধি সেরা সমাধান খুঁজে পেয়েছি। http://matplotlib.org/examples/axes_grid/demo_parasite_axes2.html

from mpl_toolkits.axes_grid1 import host_subplot
import mpl_toolkits.axisartist as AA
import matplotlib.pyplot as plt

host = host_subplot(111, axes_class=AA.Axes)
plt.subplots_adjust(right=0.75)

par1 = host.twinx()
par2 = host.twinx()

offset = 60
new_fixed_axis = par2.get_grid_helper().new_fixed_axis
par2.axis["right"] = new_fixed_axis(loc="right",
                                    axes=par2,
                                    offset=(offset, 0))

par2.axis["right"].toggle(all=True)

host.set_xlim(0, 2)
host.set_ylim(0, 2)

host.set_xlabel("Distance")
host.set_ylabel("Density")
par1.set_ylabel("Temperature")
par2.set_ylabel("Velocity")

p1, = host.plot([0, 1, 2], [0, 1, 2], label="Density")
p2, = par1.plot([0, 1, 2], [0, 3, 2], label="Temperature")
p3, = par2.plot([0, 1, 2], [50, 30, 15], label="Velocity")

par1.set_ylim(0, 4)
par2.set_ylim(1, 65)

host.legend()

plt.draw()
plt.show()

স্ট্যাক ওভারফ্লোতে স্বাগতম! টার্গেট সাইটটি যদি না পারা যায় বা স্থায়ীভাবে অফলাইনে চলে যায় তবে লিংকের সর্বাধিক প্রাসঙ্গিক অংশটি উদ্ধৃত করুন। আমি কিভাবে একটি ভাল উত্তর লিখুন দেখুন । ভবিষ্যতে আরও বর্তমান প্রশ্নগুলিতে ফোকাস করুন, এটি প্রায় 4 বছরের পুরানো।
বাইটহ্যামস্টার

প্রকৃতপক্ষে একটি ভাল সন্ধান তবে আমি আশা করি আপনি উদাহরণ থেকে যা শিখেছেন তা গ্রহণ করেছেন, ওপির এমডাব্লুইইতে প্রয়োগ করেছেন এবং একটি চিত্র অন্তর্ভুক্ত করেছেন।
এ্যারোনাটআউটো
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.