ম্যাটপ্ল্লিটব রঙ চক্রের স্থিতি পান


90

ম্যাটপ্ল্লোটিব রঙ চক্রের বর্তমান অবস্থা সম্পর্কে জিজ্ঞাসা করা কি সম্ভব? অন্য কথায় কি এমন কোনও ফাংশন রয়েছে get_cycle_stateযা নিম্নলিখিত পদ্ধতিতে আচরণ করবে?

>>> plot(x1, y1)
>>> plot(x2, y2)
>>> state = get_cycle_state()
>>> print state
2

যেখানে আমি প্রত্যাশা করব রাজ্যটি পরবর্তী রঙের সূচক হবে যা কোনও প্লটে ব্যবহৃত হবে। বিকল্পভাবে, যদি এটি পরবর্তী রঙে (উপরের উদাহরণে ডিফল্ট চক্রের জন্য "r") ফেরত দেয় তবে এটিও ঠিক থাকবে।


এটি করা যেতে পারে, এমনকি বর্তমান অবস্থা পরিবর্তন না করেও নীচের উত্তরটি দেখুন
সানচো.স রিনস্টেটমোনিকাসেলিও

উত্তর:


110

রঙচক্র পুনরুক্তি অ্যাক্সেস করা হচ্ছে

অন্তর্নিহিত পুনরাবৃত্তিকে অ্যাক্সেস করার জন্য কোনও "ব্যবহারকারীর মুখোমুখি" (ওরফে "পাবলিক") পদ্ধতি নেই তবে আপনি এটি "ব্যক্তিগত" (কনভেনশন দ্বারা) পদ্ধতিগুলির মাধ্যমে অ্যাক্সেস করতে পারেন। তবে, আপনি iteratorএটির পরিবর্তন না করে একটি রাজ্য পেতে পারবেন না ।

রঙচক্র সেট করা হচ্ছে

দ্রুত সরানো: আপনি রঙ / সম্পত্তি চক্রটি বিভিন্ন উপায়ে সেট করতে পারেন (যেমন ax.set_color_cycleসংস্করণ <1.5 বা ax.set_prop_cyclerইন> = 1.5)। সংস্করণ 1.5 বা তার বেশি বা এখানে পূর্ববর্তী শৈলীর জন্য উদাহরণটি দেখুন ।

অন্তর্নিহিত পুনরুক্তিকারী অ্যাক্সেস করা

তবে, পুনরাবৃত্তিযোগ্য অ্যাক্সেসের জন্য জনসাধারণের মুখোমুখি কোনও পদ্ধতি নেই, তবে আপনি সহায়ক শ্রেণীর উদাহরণের axমাধ্যমে কোনও প্রদত্ত অক্ষের অবজেক্টের জন্য এটি অ্যাক্সেস করতে পারবেন _get_linesax._get_linesএকটি স্পর্শ যা বিভ্রান্তিকরভাবে নামকরণ করা হয়েছে, তবে এটি পর্দার আড়ালে থাকা যন্ত্রপাতি যা plotকমান্ডকে সমস্ত অদ্ভুত এবং বিচিত্র পদ্ধতিতে কল করার অনুমতি দেয় plot। অন্যান্য জিনিসগুলির মধ্যে এটি কী রঙগুলি স্বয়ংক্রিয়ভাবে নির্ধারণ করে তা ট্র্যাক করে। একইভাবে, ax._get_patches_for_fillডিফল্ট ভরাট রঙ এবং প্যাচ বৈশিষ্ট্যগুলির মাধ্যমে সাইক্লিং নিয়ন্ত্রণ করতে হবে।

যে কোনও হারে, রঙচক্র পুনরাবৃত্তযোগ্য ax._get_lines.color_cycleলাইনগুলির ax._get_patches_for_fill.color_cycleজন্য এবং প্যাচগুলির জন্য। ম্যাটপ্ল্লোলিব> = 1.5 এ, এটি cyclerলাইব্রেরিটি ব্যবহার করতে পরিবর্তিত হয়েছে এবং এর prop_cyclerপরিবর্তে পুনরাবৃত্তিযোগ্য বলা হয় color_cycleএবং dictকেবল একটি বর্ণের পরিবর্তে বৈশিষ্ট্যগুলির একটি ফলন করে ।

সব মিলিয়ে আপনি এমন কিছু করতে চাইবেন:

import matplotlib.pyplot as plt

fig, ax = plt.subplots()
color_cycle = ax._get_lines.color_cycle
# or ax._get_lines.prop_cycler on version >= 1.5
# Note that prop_cycler cycles over dicts, so you'll want next(cycle)['color']

আপনি কোনটির অবস্থা দেখতে পারবেন না iterator

তবে এই বস্তুটি একটি "বেয়ার" iterator। আমরা খুব সহজেই পরবর্তী আইটেম (যেমন পেতে পারেন next_color = next(color_cycle), কিন্তু তার মানে তাদের পরবর্তী রঙ যে পরে কি অঙ্কিত করা হবে। নকশা দ্বারা, সেখানে এটি পরিবর্তন না করে কোনো ইটারেটরে বর্তমান অবস্থা পাওয়ার কোন উপায়।

ইন v1.5বা তার অধিক, এটি পেতে চমৎকার হবে cyclerবস্তুর যে ব্যবহার আমরা এটির বর্তমান অবস্থায় আবিষ্কার পারে। তবে, cyclerঅবজেক্টটি নিজেই কোথাও অ্যাক্সেসযোগ্য নয় (প্রকাশ্যে বা ব্যক্তিগতভাবে)। পরিবর্তে, কেবলমাত্র বস্তুটি itertools.cycleথেকে তৈরি দৃষ্টান্তটি cyclerঅ্যাক্সেসযোগ্য। যে কোনও উপায়ে, রঙ / সম্পত্তি সাইক্লারের অন্তর্নিহিত অবস্থায় যাওয়ার কোনও উপায় নেই।

পরিবর্তে আগের প্লট করা আইটেমের রঙটি মিলান

আপনার ক্ষেত্রে এটির মতো শোনা যাচ্ছে যে আপনি সবেমাত্র ষড়যন্ত্র করা কোনও রঙের সাথে মেলে করতে চান। রঙ / সম্পত্তি কী হবে তা নির্ধারণের পরিবর্তে, কী পরিকল্পনা করা হয়েছে তার বৈশিষ্ট্যের ভিত্তিতে আপনার নতুন আইটেমের রঙ / ইত্যাদি সেট করুন।

উদাহরণস্বরূপ, আপনি বর্ণিত ক্ষেত্রে, আমি এই জাতীয় কিছু করব:

import matplotlib.pyplot as plt
import numpy as np

def custom_plot(x, y, **kwargs):
    ax = kwargs.pop('ax', plt.gca())
    base_line, = ax.plot(x, y, **kwargs)
    ax.fill_between(x, 0.9*y, 1.1*y, facecolor=base_line.get_color(), alpha=0.5)

x = np.linspace(0, 1, 10)
custom_plot(x, x)
custom_plot(x, 2*x)
custom_plot(x, -x, color='yellow', lw=3)

plt.show()

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

একমাত্র উপায় নয়, তবে এই ক্ষেত্রে প্লট করা লাইনের রঙ পাওয়ার চেষ্টা করার চেয়ে তার ক্লিনার।


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

12
আপনি যদি কেবল কোনও নির্দিষ্ট সামগ্রীর রঙের সাথে মিল রাখতে চান তবে আপনি সর্বদা এটির রঙ ধরতে পারেন। উদাহরণস্বরূপ line, = ax.plot(x, y)এবং তারপরে line.get_color()পূর্ব-প্লট করা লাইনের রঙ পেতে ব্যবহার করুন ।
জো কিংটন

4
মনে হয় ax._get_lines.color_cycleএখন আর 1.5 তে নেই?
এন্ডোলিথ

6
আমি মনে করি (নিকটে) সমতুল্য একটি iterable হয় ax._get_lines.prop_cyclerতোমার মত কনস্ট্রাক্ট কিছু থাকতে পারে if 'color' in ax._get_lines._prop_keys:দ্বারা অনুসরণ next(ax._get_lines.prop_cycler)['color']কি দিয়ে পরামর্শ দেওয়া হয় সমতুল্য করতে color_cycleউত্তর, আমি বিশ্বাস করি। আপনি কেবল রঙের পুনরাবৃত্তিযোগ্য পেতে পারেন কিনা তা আমি নিশ্চিত নই, আমার আরও অনুসন্ধান করতে হবে।
জে রিচার্ড স্নেপ

4
@ এন্ডোলিথ শিওর (এবং ধন্যবাদ) - তবে আমি কেবল অনুভব করেছি যে জো এর ইতিমধ্যে খুব ভাল এবং গ্রহণযোগ্য উত্তরে বসে থাকলে ভাল হবে। যদি সে সোমবারের মধ্যে এটি রাখে না - আমি ভয়ঙ্কর "উত্তর-মন্তব্যে" পরিবর্তে সেখানে একটি যথাযথ জবাব দেব
জে রিচার্ড স্নেপ

26

এখানে 1.5-তে কাজ করার একটি উপায় রয়েছে যা আন্ডারস্কোরগুলি সহ প্রিপেন্ড করা পদ্ধতিগুলির উপর নির্ভর করে না বলে আশাবাদী ভবিষ্যত-প্রমাণ হবে:

colors = plt.rcParams["axes.prop_cycle"].by_key()["color"]

এটি আপনাকে বর্তমান শৈলীর জন্য বর্ণিত রঙগুলির একটি তালিকা দেবে।


4
২.০.২ এ কাজ করে।
কেভিনজি

16

দ্রষ্টব্য: ম্যাটপ্ল্লোলিব (> = 1.5) এর সর্বশেষ সংস্করণে _get_linesপরিবর্তন হয়েছে। আপনি এখন ব্যবহার করতে হবে next(ax._get_lines.prop_cycler)['color']পাইথন 2 বা 3 (অথবা ax._get_lines.prop_cycler.next()['color']মধ্যে পাইথন 2 ) রঙ চক্র থেকে পরবর্তী রঙ জন্য।

@ জো-কিংটনের উত্তরের নীচের অংশে যেখানেই সম্ভব আরও বেশি সরাসরি পদ্ধতির ব্যবহার করুন। হিসাবে _get_linesনয় এপিআই ফেসিং এটা ভবিষ্যতে একটি না অনগ্রসর সামঞ্জস্যপূর্ণ পদ্ধতিতে আবার পরিবর্তিত হতে পারে।


আপনি কীভাবে এড়াতে পারবেন যে রঙ সাইক্লারের পরবর্তী উপাদানটির অনুসন্ধান করা সাইক্লারের স্থিতি পরিবর্তন করে?
কাজেমকাসে

6

অবশ্যই, এটি এটি করবে।

#rainbow

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(0,2*np.pi)
ax= plt.subplot(1,1,1)
ax.plot(np.sin(x))
ax.plot(np.cos(x))

rainbow = ax._get_lines.color_cycle
print rainbow
for i, color in enumerate(rainbow):
    if i<10:
        print color,

দেয়:

<itertools.cycle object at 0x034CB288>
r c m y k b g r c m

এখানে ম্যাটারপ্লোলিব এটির্টোলগুলি ব্যবহার করে uses

সম্পাদনা: মন্তব্যের জন্য ধন্যবাদ, মনে হচ্ছে কোনও পুনরুক্তিকারীর অনুলিপি করা সম্ভব নয়। একটি ধারণাটি হ'ল একটি সম্পূর্ণ চক্র ডাম্প করা এবং আপনি কোন মানটি ব্যবহার করছেন তা ট্র্যাক করে রাখুন, আমাকে সেটিতে ফিরে আসুন।

সম্পাদনা 2: ঠিক আছে, এটি আপনাকে পরবর্তী রঙ দেবে এবং একটি নতুন পুনরাবৃত্তি তৈরি করবে যা এমন আচরণ করে যা পরেরটিকে বলা হয়নি। এটি রঙের ক্রম সংরক্ষণ করে না, কেবল পরের রঙের মানটি, আমি এটি আপনার কাছে রেখে দিই।

এটি নিম্নলিখিত আউটপুট দেয়, লক্ষ্য করুন যে প্লটের খাড়া হওয়া সূচকের সাথে মিলেছে, যেমন প্রথম জি হ'ল তলদেশীয় গ্রাফ এবং তাই।

#rainbow

import matplotlib.pyplot as plt
import numpy as np
import collections
import itertools

x = np.linspace(0,2*np.pi)
ax= plt.subplot(1,1,1)


def create_rainbow():
    rainbow = [ax._get_lines.color_cycle.next()]
    while True:
        nextval = ax._get_lines.color_cycle.next()
        if nextval not in rainbow:
            rainbow.append(nextval)
        else:
            return rainbow

def next_color(axis_handle=ax):
    rainbow = create_rainbow()
    double_rainbow = collections.deque(rainbow)
    nextval = ax._get_lines.color_cycle.next()
    double_rainbow.rotate(-1)
    return nextval, itertools.cycle(double_rainbow)


for i in range(1,10):
    nextval, ax._get_lines.color_cycle = next_color(ax)
    print "Next color is: ", nextval
    ax.plot(i*(x))


plt.savefig("SO_rotate_color.png")
plt.show()

কনসোল

Next color is:  g
Next color is:  c
Next color is:  y
Next color is:  b
Next color is:  r
Next color is:  m
Next color is:  k
Next color is:  g
Next color is:  c

রঙ ঘোরান


ধন্যবাদ! কেবল স্পষ্ট করে বলতে গেলে, এটি কোনও অনুলিপি ফেরত দেয় বলে মনে হয় না, বরং প্রকৃত চক্রের একটি রেফারেন্স। সুতরাং, রংধনু.নেক্সট () কল করা আসলে পরবর্তী প্লটটি দেখতে কেমন হবে তা পরিবর্তন করতে চলেছে।
mwaskom

5

আমি শুধু অ্যান্ডি উপরে যা বলেছি তাতে আমি যুক্ত করতে চাই। যেহেতু color_cycleম্যাটপ্লোটিব 1.5 তে অবহেলিত, তাই আপনাকে ব্যবহার করতে হবে prop_cyclerতবে অ্যান্ডির সমাধান ( ax._get_lines.prop_cycler.next()['color']) আমার জন্য এই ত্রুটি ফিরিয়ে দিয়েছে:

অ্যাট্রিবিউটআরার: 'ইটার্টোলস.সাইক্ল' অবজেক্টটির 'পরের' বৈশিষ্ট্য নেই

আমার পক্ষে যে কোডটি কাজ করেছিল তা হ'ল: next(ax._get_lines.prop_cycler)যা আসলে @ জো-কিংটনের মূল প্রতিক্রিয়া থেকে খুব বেশি দূরে নয়।

ব্যক্তিগতভাবে, একটি দ্বিগুণ () অক্ষ তৈরি করার সময় আমি এই সমস্যায় পড়েছিলাম, যা রঙ সাইকেলটি পুনরায় সেট করে। রঙগুলি চক্রটিকে সঠিকভাবে তৈরি করার জন্য আমার একটি উপায়ের প্রয়োজন ছিল কারণ আমি ব্যবহার করছি style.use('ggplot')। এটি করার সহজতর / আরও ভাল উপায় হতে পারে, তাই আমাকে সংশোধন করতে দ্বিধা বোধ করুন।


দয়া করে আপনার পোস্টকে একটি আলোচনার উপাদান হিসাবে নয়, উত্তর হিসাবে ফর্ম্যাট করুন (অন্যথায় এটি একটি মন্তব্য), আপনার মূল বিষয়টি হ'ল next(ax._get_lines.prop_cycler)সম্ভাব্য বিকল্প।
উমনিওব

@ কারসন আপনি কীভাবে এড়াতে পারবেন যে কলটি next(ax._get_lines.prop_cycler)আসলে রঙিন সাইক্লারের অবস্থা পরিবর্তন করে?
কাজেমকাসে

এটাই আসলে আমি করার চেষ্টা করছিলাম - এর অবস্থার পরিবর্তন করুন prop_cycler। আপনি যদি এই প্রশ্নের গৃহীত উত্তরটি পড়ে থাকেন তবে আপনি দেখতে পাবেন যে prop_cyclerতার অবস্থার পরিবর্তন না করে রাষ্ট্রের অ্যাক্সেসের কোনও উপায় নেই কারণ এটি পুনরাবৃত্তিযোগ্য।
কারসন

আপনি যে ত্রুটিটি চিহ্নিত করেছেন তা হলেন পাইথন 2 / পাইথন 3 পার্থক্য। এটি নির্দেশ করার জন্য ধন্যবাদ, আমি সেই অনুযায়ী আমার উত্তর সম্পাদনা করেছি।
Andi

1

যেহেতু ম্যাটপ্ল্লোব ব্যবহার করে itertools.cycleআমরা প্রকৃতপক্ষে পুরো রঙ চক্রটি দেখতে পারি এবং তারপরে পুনরুক্তিটিকে পূর্বের অবস্থায় ফিরিয়ে আনতে পারি:

def list_from_cycle(cycle):
    first = next(cycle)
    result = [first]
    for current in cycle:
        if current == first:
            break
        result.append(current)

    # Reset iterator state:
    for current in cycle:
        if current == result[-1]:
            break
    return result

এটি পুনরাবৃত্তির স্থিতি পরিবর্তন না করে তালিকাটি ফিরিয়ে আনতে হবে।

এটি ম্যাটপ্ল্লোলিব> = 1.5 এর সাথে ব্যবহার করুন:

>>> list_from_cycle(ax._get_lines.prop_cycler)
[{'color': 'r'}, {'color': 'g'}, {'color': 'b'}]

বা ম্যাটপ্ল্লিটিব <1.5:

>>> list_from_cycle(ax._get_lines.color_cycle)
['r', 'g', 'b']


-1

ম্যাটপ্ল্লোব সংস্করণ ২.২.৩ get_next_color()_get_linesসম্পত্তি সম্পর্কে একটি পদ্ধতি রয়েছে :

import from matplotlib import pyplot as plt
fig, ax = plt.subplots()
next_color = ax._get_lines.get_next_color()

get_next_color() একটি এইচটিএমএল রঙের স্ট্রিং প্রদান করে এবং রঙ চক্র পুনরাবৃত্তকারীকে অগ্রসর করে।


-1

রঙ (এবং সম্পূর্ণ শৈলী) চক্রটি কীভাবে অ্যাক্সেস করবেন?

বর্তমান অবস্থা সংরক্ষণ করা হয় ax._get_lines.prop_cycler। জেনেরিকের এবং " itertools.cycleবিশেষত ax._get_lines.prop_cyclerনীচে দেখুন " এর জন্য "বেস তালিকা" প্রকাশের জন্য অন্তর্নির্মিত কোনও পদ্ধতি নেই।

এ সম্পর্কিত তথ্য পেতে আমি এখানে কয়েকটি ফাংশন পোস্ট করেছি itertools.cycle। এক তারপর ব্যবহার করতে পারে

style_cycle = ax._get_lines.prop_cycler
curr_style = get_cycle_state(style_cycle)  # <-- my (non-builtin) function
curr_color = curr_style['color']

চক্রের স্থিতি পরিবর্তন না করে বর্তমান রঙটি পেতে ।


টিএল; ডিআর

রঙ (এবং সম্পূর্ণ শৈলী) চক্রটি কোথায় সঞ্চয় করা হয়?

শৈলী চক্র দুটি ভিন্ন জায়গা, এক মধ্যে সংরক্ষিত হয় ডিফল্ট , এবং এক বর্তমান অক্ষ (অভিমানী import matplotlib.pyplot as pltএবং axএকজন অক্ষ হ্যান্ডলার):

default_prop_cycler = plt.rcParams['axes.prop_cycle']
current_prop_cycle = ax._get_lines.prop_cycler

নোট করুন এগুলির বিভিন্ন ক্লাস রয়েছে। ডিফল্ট হ'ল "বেস চক্র সেটিং" এবং এটি কোনও অক্ষের জন্য কোনও বর্তমান অবস্থা সম্পর্কে জানে না, যখন বর্তমানটি চক্রটি অনুসরণ এবং তার বর্তমান অবস্থা সম্পর্কে জানে:

print('type(default_prop_cycler) =', type(default_prop_cycler))
print('type(current_prop_cycle) =', type(current_prop_cycle))

[]: type(default_prop_cycler) = <class 'cycler.Cycler'>
[]: type(current_prop_cycle) = <class 'itertools.cycle'>

ডিফল্ট চক্রটিতে চক্রের কয়েকটি কী (বৈশিষ্ট্য) থাকতে পারে এবং কেবলমাত্র রঙগুলি পেতে পারে:

print('default_prop_cycler.keys =', default_prop_cycler.keys)
default_prop_cycler2 = plt.rcParams['axes.prop_cycle'].by_key()
print(default_prop_cycler2)
print('colors =', default_prop_cycler2['color'])

[]: default_prop_cycler.keys = {'color', 'linestyle'}
[]: {'color': ['r', 'g', 'b', 'y'], 'linestyle': ['-', '--', ':', '-.']}
[]: colors = ['r', 'g', 'b', 'y']

এমনকি cyclerএকটি axesপ্রদত্তের custom_prop_cyclerসাথে এটির সংজ্ঞা দেওয়ার পরে ব্যবহারের পরিবর্তনও করতে পারে

ax.set_prop_cycle(custom_prop_cycler)

তবে জেনেরিকের এবং " itertools.cycleবিশেষত " জন্য "বেস তালিকা" প্রকাশের জন্য কোনও অন্তর্নির্মিত পদ্ধতি নেই ax._get_lines.prop_cycler

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.