Matplotlib में उल्टा कॉलोर्माप


253

मैं यह जानना चाहूंगा कि प्लॉट_सर्फ़ के साथ इसका उपयोग करने के लिए किसी दिए गए कॉलोरामैप के रंग क्रम को कैसे उल्टा करना है।

जवाबों:


464

मानक colormaps भी सभी उलट संस्करण हैं। _rअंत तक उनसे निपटने के साथ उनके नाम समान हैं । ( यहां प्रलेखन। )


यह "amfhot" के साथ काम नहीं करता है: "ValueError: Colormap amfhot_r मान्यता प्राप्त नहीं है"। मुझे लगता है कि "hot_r" को सहना होगा।
शॉकबर्नर

इसी तरह, "ValueError: Colormap red_r मान्यता प्राप्त नहीं है।"
एलेक्स विलीसन

18

Matplotlib में एक रंग का नक्शा एक सूची नहीं है, लेकिन इसमें इसके रंगों की सूची शामिल है colormap.colors। और मॉड्यूल एक सूची से एक रंग नक्शा बनाने के लिए matplotlib.colorsएक फ़ंक्शन प्रदान करता है ListedColormap()। तो आप किसी भी रंग के नक्शे को उल्टा कर सकते हैं

colormap_r = ListedColormap(colormap.colors[::-1])

7
+1। हालाँकि, यह उदारता से किसी भी कॉलॉर्मैप को उलट नहीं करेगा। केवल ListedColormapएस (यानी असतत के बजाय असतत) की colorsविशेषता है। उलटना LinearSegmentedColormapsथोड़ा अधिक जटिल है। (आपको प्रत्येक आइटम को _segmentdataतानाशाही में उलटने की आवश्यकता है ।)
जो किंगटन

3
उलटने के बारे में LinearSegmentedColormaps, मैंने अभी कुछ कोलोरैप्स के लिए ऐसा किया था। यहाँ इसके बारे में एक IPython नोटबुक है।
kwinkunks

@kwinkcks मुझे लगता है कि आपकी नोटबुक में फ़ंक्शन सही नहीं है, नीचे उत्तर देखें
मैटिंज़

14

समाधान बहुत सीधा है। मान लीजिए कि आप "शरद ऋतु" कॉलोरामैप योजना का उपयोग करना चाहते हैं। मानक संस्करण:

cmap = matplotlib.cm.autumn

Colormap रंग स्पेक्ट्रम को उल्टा करने के लिए, get_cmap () फ़ंक्शन का उपयोग करें और colormap शीर्षक जैसे '_r' को जोड़ें:

cmap_reversed = matplotlib.cm.get_cmap('autumn_r')

क्या आप प्रलेखन लिंक प्रदान कर सकते हैं जहाँ आपको।
Xitcod13

यह बाद में टूट सकता है ... matplotlib.org/3.1.1/gallery/color/colormap_reference.html , लेकिन मुझे यकीन है कि किसी को भी दिलचस्पी किसी भी तरह से खोज करने से मिल जाएगी।
जलंगर

13

चूंकि LinearSegmentedColormapsयह लाल, हरे और नीले रंग के शब्दकोश पर आधारित है, इसलिए प्रत्येक आइटम को उल्टा करना आवश्यक है:

import matplotlib.pyplot as plt
import matplotlib as mpl
def reverse_colourmap(cmap, name = 'my_cmap_r'):
    """
    In: 
    cmap, name 
    Out:
    my_cmap_r

    Explanation:
    t[0] goes from 0 to 1
    row i:   x  y0  y1 -> t[0] t[1] t[2]
                   /
                  /
    row i+1: x  y0  y1 -> t[n] t[1] t[2]

    so the inverse should do the same:
    row i+1: x  y1  y0 -> 1-t[0] t[2] t[1]
                   /
                  /
    row i:   x  y1  y0 -> 1-t[n] t[2] t[1]
    """        
    reverse = []
    k = []   

    for key in cmap._segmentdata:    
        k.append(key)
        channel = cmap._segmentdata[key]
        data = []

        for t in channel:                    
            data.append((1-t[0],t[2],t[1]))            
        reverse.append(sorted(data))    

    LinearL = dict(zip(k,reverse))
    my_cmap_r = mpl.colors.LinearSegmentedColormap(name, LinearL) 
    return my_cmap_r

देखें कि यह काम करता है:

my_cmap        
<matplotlib.colors.LinearSegmentedColormap at 0xd5a0518>

my_cmap_r = reverse_colourmap(my_cmap)

fig = plt.figure(figsize=(8, 2))
ax1 = fig.add_axes([0.05, 0.80, 0.9, 0.15])
ax2 = fig.add_axes([0.05, 0.475, 0.9, 0.15])
norm = mpl.colors.Normalize(vmin=0, vmax=1)
cb1 = mpl.colorbar.ColorbarBase(ax1, cmap = my_cmap, norm=norm,orientation='horizontal')
cb2 = mpl.colorbar.ColorbarBase(ax2, cmap = my_cmap_r, norm=norm, orientation='horizontal')

यहां छवि विवरण दर्ज करें

संपादित करें


मुझे user3445587 की टिप्पणी नहीं मिली। यह इंद्रधनुष कोलोरम पर ठीक काम करता है:

cmap = mpl.cm.jet
cmap_r = reverse_colourmap(cmap)

fig = plt.figure(figsize=(8, 2))
ax1 = fig.add_axes([0.05, 0.80, 0.9, 0.15])
ax2 = fig.add_axes([0.05, 0.475, 0.9, 0.15])
norm = mpl.colors.Normalize(vmin=0, vmax=1)
cb1 = mpl.colorbar.ColorbarBase(ax1, cmap = cmap, norm=norm,orientation='horizontal')
cb2 = mpl.colorbar.ColorbarBase(ax2, cmap = cmap_r, norm=norm, orientation='horizontal')

यहां छवि विवरण दर्ज करें

लेकिन यह विशेष रूप से कस्टम घोषित कॉलॉर्मैप्स के लिए अच्छा काम करता है, क्योंकि _rकस्टम घोषित कॉलोर्मैप्स के लिए डिफ़ॉल्ट नहीं है । Http://matplotlib.org/examples/pylab_examples/custom_cmap.html से लिए गए उदाहरण के बाद :

cdict1 = {'red':   ((0.0, 0.0, 0.0),
                   (0.5, 0.0, 0.1),
                   (1.0, 1.0, 1.0)),

         'green': ((0.0, 0.0, 0.0),
                   (1.0, 0.0, 0.0)),

         'blue':  ((0.0, 0.0, 1.0),
                   (0.5, 0.1, 0.0),
                   (1.0, 0.0, 0.0))
         }

blue_red1 = mpl.colors.LinearSegmentedColormap('BlueRed1', cdict1)
blue_red1_r = reverse_colourmap(blue_red1)

fig = plt.figure(figsize=(8, 2))
ax1 = fig.add_axes([0.05, 0.80, 0.9, 0.15])
ax2 = fig.add_axes([0.05, 0.475, 0.9, 0.15])

norm = mpl.colors.Normalize(vmin=0, vmax=1)
cb1 = mpl.colorbar.ColorbarBase(ax1, cmap = blue_red1, norm=norm,orientation='horizontal')
cb2 = mpl.colorbar.ColorbarBase(ax2, cmap = blue_red1_r, norm=norm, orientation='horizontal')

यहां छवि विवरण दर्ज करें


यह उदाहरण इस अर्थ में पूर्ण नहीं है कि सेगमेंट्डता सूचियों में नहीं है, इसलिए यह जरूरी नहीं है कि यह प्रतिवर्ती है (जैसे मानक इंद्रधनुष कॉलोर्मप)। मुझे लगता है कि सिद्धांत रूप में सभी LinearSelectedColormaps को रेंबो कॉलॉर्मैप के रूप में लैंबडा फ़ंक्शन का उपयोग करके प्रिसीबल में प्रतिवर्ती होना चाहिए?
विदेशों में

@ user3445587 मैं कुछ और उदाहरण जोड़ता हूं, लेकिन मुझे लगता है कि यह मानक इंद्रधनुष
कॉलॉर्मप

चूंकि यह बहुत लंबा था, इसलिए मैंने एक नया उत्तर जोड़ा, जो सभी प्रकार के लिनियरशिपडाटा के लिए काम करना चाहिए। समस्या यह है कि इंद्रधनुष के लिए, _segmentdata को अलग तरीके से लागू किया जाता है। तो आपका कोड - कम से कम मेरी मशीन पर - इंद्रधनुष कॉलोर्मैप के साथ काम नहीं करता है।
विदेशी

12

Matplotlib 2.0 के रूप में, वहाँ और वस्तुओं के reversed()लिए एक विधि है , तो आप बस कर सकते हैंListedColormapLinearSegmentedColorMap

cmap_reversed = cmap.reversed()

यहाँ प्रलेखन है।


1

LinearSegmentedColormaps दो प्रकार के होते हैं। कुछ में, _segmentdata जेट के लिए स्पष्ट रूप से दिया जाता है, जैसे:

>>> cm.jet._segmentdata
{'blue': ((0.0, 0.5, 0.5), (0.11, 1, 1), (0.34, 1, 1), (0.65, 0, 0), (1, 0, 0)), 'red': ((0.0, 0, 0), (0.35, 0, 0), (0.66, 1, 1), (0.89, 1, 1), (1, 0.5, 0.5)), 'green': ((0.0, 0, 0), (0.125, 0, 0), (0.375, 1, 1), (0.64, 1, 1), (0.91, 0, 0), (1, 0, 0))}

इंद्रधनुष के लिए, _segmentdata निम्नानुसार दिया गया है:

>>> cm.rainbow._segmentdata
{'blue': <function <lambda> at 0x7fac32ac2b70>, 'red': <function <lambda> at 0x7fac32ac7840>, 'green': <function <lambda> at 0x7fac32ac2d08>}

हम माटप्लोटलिब के स्रोत में कार्यों को पा सकते हैं, जहां वे दिए गए हैं

_rainbow_data = {
        'red': gfunc[33],   # 33: lambda x: np.abs(2 * x - 0.5),
        'green': gfunc[13], # 13: lambda x: np.sin(x * np.pi),
        'blue': gfunc[10],  # 10: lambda x: np.cos(x * np.pi / 2)
}

सब कुछ जो आप चाहते हैं, पहले से ही matplotlib में किया जाता है, बस cm.revcmap को कॉल करें, जो दोनों प्रकार के सेगमेंटेट को उलट देता है, इसलिए

cm.revcmap(cm.rainbow._segmentdata)

काम करना चाहिए - आप बस एक नया LinearSegmentData बना सकते हैं। Revcmap में, फ़ंक्शन आधारित SegmentData का उत्क्रमण किया जाता है

def _reverser(f):
    def freversed(x):
        return f(1 - x)
    return freversed

जबकि अन्य सूचियों को हमेशा की तरह उलट दिया जाता है

valnew = [(1.0 - x, y1, y0) for x, y0, y1 in reversed(val)] 

तो वास्तव में पूरी चीज आप चाहते हैं, है

def reverse_colourmap(cmap, name = 'my_cmap_r'):
     return mpl.colors.LinearSegmentedColormap(name, cm.revcmap(cmap._segmentdata)) 

1

मनमाने ढंग से कॉलोर्मैप्स को उलटने का कोई अंतर्निहित तरीका (अभी तक) नहीं है, लेकिन एक सरल उपाय यह है कि वास्तव में कलरबार को संशोधित नहीं किया जाए, बल्कि एक इनवर्टिंग नॉर्मलाइज़ ऑब्जेक्ट बनाने के लिए:

from matplotlib.colors import Normalize

class InvertedNormalize(Normalize):
    def __call__(self, *args, **kwargs):
        return 1 - super(InvertedNormalize, self).__call__(*args, **kwargs)

तब आप इसके साथ plot_surfaceऔर अन्य Matplotlib साजिश रचने वाले कार्यों का उपयोग कर सकते हैं

inverted_norm = InvertedNormalize(vmin=10, vmax=100)
ax.plot_surface(..., cmap=<your colormap>, norm=inverted_norm)

यह किसी भी Matplotlib colormap के साथ काम करेगा।


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