Mendapatkan warna individual dari peta warna di matplotlib

136

Jika Anda memiliki Colormap cmap, misalnya:

cmap = matplotlib.cm.get_cmap('Spectral')

Bagaimana Anda bisa mendapatkan warna tertentu dari antara 0 dan 1, di mana 0 adalah warna pertama di peta dan 1 adalah warna terakhir di peta?

Idealnya, saya bisa mendapatkan warna tengah di peta dengan melakukan:

>>> do_some_magic(cmap, 0.5) # Return an RGBA tuple
(0.1, 0.2, 0.3, 1.0)
LondonRob
sumber

Jawaban:

219

Anda dapat melakukan ini dengan kode di bawah ini, dan kode dalam pertanyaan Anda sebenarnya sangat dekat dengan apa yang Anda butuhkan, yang harus Anda lakukan adalah memanggil cmapobjek yang Anda miliki.

import matplotlib

cmap = matplotlib.cm.get_cmap('Spectral')

rgba = cmap(0.5)
print(rgba) # (0.99807766255210428, 0.99923106502084169, 0.74602077638401709, 1.0)

Untuk nilai di luar rentang [0,0, 1.0] itu akan mengembalikan warna di bawah dan di atas (masing-masing). Ini, secara default, adalah warna minimum dan maksimum dalam rentang (jadi 0,0 dan 1,0). Default ini dapat diubah dengan cmap.set_under()dan cmap.set_over().

Untuk angka "khusus" seperti np.nandan np.infstandarnya adalah menggunakan nilai 0,0, ini dapat diubah menggunakan cmap.set_bad()mirip dengan di bawah dan di atas seperti di atas.

Akhirnya mungkin perlu bagi Anda untuk menormalkan data Anda sedemikian rupa sehingga sesuai dengan rentang [0.0, 1.0]. Ini dapat dilakukan dengan menggunakan matplotlib.colors.Normalizehanya seperti yang ditunjukkan pada contoh kecil di bawah ini di mana argumen vmindan vmaxmenggambarkan angka apa yang harus dipetakan masing-masing 0,0 dan 1,0.

import matplotlib

norm = matplotlib.colors.Normalize(vmin=10.0, vmax=20.0)

print(norm(15.0)) # 0.5

Normaliser logaritmik ( matplotlib.colors.LogNorm ) juga tersedia untuk rentang data dengan rentang nilai yang besar.

(Terima kasih kepada Joe Kington dan tcaswell untuk saran tentang cara meningkatkan jawaban.)

Ffisegydd
sumber
3
Sebenarnya, untuk nilai kurang dari 0 atau lebih dari 1 akan mengembalikan warna "lebih" atau "di bawah". Secara default itu warna di bagian bawah / atas colormap, tapi itu bisa diubah. Sebagai contoh: cmap.set_under('red'); print cmap(0.0), cmap(-0.01)
Joe Kington
Hai @ Jo, terima kasih atas koreksinya, saya telah memodifikasi jawaban saya :)
Ffisegydd
Ada juga set_badyang mendefinisikan untuk apa iirc np.nandan np.infiirc. Anda harus menyebutkan Normalizemetode di sini juga.
tacaswell
12
Informasi yang sangat berguna dan mengapa tidak mungkin menemukan ini di dokumentasi!?!
Jaap Eldering
10
Jika ini tidak berhasil untuk siapa pun, dan Anda lihat module 'matplotlib' has no attribute 'cm', coba ganti dua baris pertama denganimport matplotlib.pyplot as plt; cmap = plt.cm.get_cmap('Spectral')
Anonim
9

Untuk mendapatkan nilai integer rgba alih-alih nilai float, bisa kita lakukan

rgba = cmap(0.5,bytes=True)

Jadi untuk menyederhanakan kode berdasarkan jawaban dari Ffisegydd, kodenya akan seperti ini:

#import colormap
from matplotlib import cm

#normalize item number values to colormap
norm = matplotlib.colors.Normalize(vmin=0, vmax=1000)

#colormap possible values = viridis, jet, spectral
rgba_color = cm.jet(norm(400),bytes=True) 

#400 is one of value between 0 and 1000
amaliammr
sumber
0

Untuk membangun solusi dari Ffisegydd dan amaliammr , berikut adalah contoh di mana kami membuat representasi CSV untuk colormap khusus:

#! /usr/bin/env python3
import matplotlib
import numpy as np 

vmin = 0.1
vmax = 1000

norm = matplotlib.colors.Normalize(np.log10(vmin), np.log10(vmax))
lognum = norm(np.log10([.5, 2., 10, 40, 150,1000]))

cdict = {
    'red':
    (
        (0., 0, 0),
        (lognum[0], 0, 0),
        (lognum[1], 0, 0),
        (lognum[2], 1, 1),
        (lognum[3], 0.8, 0.8),
        (lognum[4], .7, .7),
    (lognum[5], .7, .7)
    ),
    'green':
    (
        (0., .6, .6),
        (lognum[0], 0.8, 0.8),
        (lognum[1], 1, 1),
        (lognum[2], 1, 1),
        (lognum[3], 0, 0),
        (lognum[4], 0, 0),
    (lognum[5], 0, 0)
    ),
    'blue':
    (
        (0., 0, 0),
        (lognum[0], 0, 0),
        (lognum[1], 0, 0),
        (lognum[2], 0, 0),
        (lognum[3], 0, 0),
        (lognum[4], 0, 0),
    (lognum[5], 1, 1)
    )
}


mycmap = matplotlib.colors.LinearSegmentedColormap('my_colormap', cdict, 256)   
norm = matplotlib.colors.LogNorm(vmin, vmax)
colors = {}
count = 0
step_size = 0.001
for value in np.arange(vmin, vmax+step_size, step_size):
    count += 1
    print("%d/%d %f%%" % (count, vmax*(1./step_size), 100.*count/(vmax*(1./step_size))))
    rgba = mycmap(norm(value), bytes=True)
    color = (rgba[0], rgba[1], rgba[2])
    if color not in colors.values():
        colors[value] = color

print ("value, red, green, blue")
for value in sorted(colors.keys()):
    rgb = colors[value]
    print("%s, %s, %s, %s" % (value, rgb[0], rgb[1], rgb[2]))
Morten
sumber
0

Untuk kelengkapan ini, ini adalah pilihan cmap yang saya temui sejauh ini:

Aksen, Accent_r, Blues, Blues_r, BrBG, BrBG_r, BuGn, BuGn_r, BuPu, BuPu_r, CMRmap, CMRmap_r, GnBu, GnBu_r, Greens, Greens_r, Grays, Greys_r, ORRd, Orr, Orr, Orr, Orr, Orr, Orr, Orr, Orr, Orr, Orr, Orr, Orr, Orr, Orr, Orr, Orr, Orr, Orr, Orr, Orr, Orr, Orr, Orr PRGn_r, Dipasangkan, Paired_r, Pastel1, Pastel1_r, Pastel2_r, PiYG, PiYG_r, PuBu, PuBuGn, PuBuGn_r, PuBu_r, PuOr, PuOr_r, PuR, PuRd, PuRd, jalan, jalan, jalan, jalan, jalan, jalan RdYlBu, RdYlBu_r, RdYlGn, RdYlGn_r, Reds, Reds_r, Set1, Set1_r, Set2, Set2_r, Set3, Set3_r, Spectral_r, Wistia, Wistia_r, YlGn, YrGr, Yr, Yr, Yr, Yr, Yr, Yr, Yr, Yr, Yr, Yr afmhot_r, musim gugur, autumn_r, biner, binary_r, tulang, bone_r, brg, brg_r, bwr, bwr_r, cividis, cividis_r, keren, keren_r, coolwarm_r, tembaga, tembaga_r, cubehelix, cubehelix_r, garth, bendera, benderagist_gray, gist_gray_r, gist_heat, gist_heat_r, gist_ncar_r, gist_rainbow, gist_rainbow_r, gist_stern_r, gist_yarg, gist_yarg_r, gnuplot, gnuplot, gnuplot, gnuplot, gnuplot, gbr jet_r, magma, magma_r, nipy_spectral, nipy_spectral_r, lautan, ocean_r, pink, pink_r, plasma, plasma_r, prisma, prism_r, pelangi, pelangi_r, seismik, seismik_r, musim semi, spring_r, musim panas, summer_r, tab10, tab10, tab10_10 tab20b, tab20b_r, tab20c, tab20c_r, medan, terrain_r, twilight, twilight_r, twilight_shifted, twilight_shifted_r, viridis, viridis_r, musim dingin, winter_rgray_r, hot, hot_r, hsv, hsv_r, inferno, inferno_r, jet, jet_r, magma, magma_r, nipy_spectral, samudra, samudra_r, pink, pink_r, plasma, plasma_r, prisma, prism_r, seismik, hujan ombak, rainbow_r_rr musim semi, spring_r, musim panas, summer_r, tab10, tab10_r, tab20, tab20_r, tab20b, tab20b_r, tab20c, tab20c_r, medan, medan_r, twilight_r, twilight_shifted, twilight_shifted_r, viridis, musim dingin _ musim dingingray_r, hot, hot_r, hsv, hsv_r, inferno, inferno_r, jet, jet_r, magma, magma_r, nipy_spectral, samudra, samudra_r, pink, pink_r, plasma, plasma_r, prisma, prism_r, seismik, hujan ombak, rainbow_r_rr musim semi, spring_r, musim panas, summer_r, tab10, tab10_r, tab20, tab20_r, tab20b, tab20b_r, tab20c, tab20c_r, medan, medan_r, twilight_r, twilight_shifted, twilight_shifted_r, viridis, musim dingin _ musim dinginviridis, viridis_r, musim dingin, winter_rviridis, viridis_r, musim dingin, winter_r

prosti
sumber