ম্যাটপ্ল্লিটিব বিচ্ছিন্ন রঙবার


99

আমি ম্যাটপ্লটলিবের স্ক্যাটারপ্ল্লটের জন্য আলাদা রঙিন বারবার তৈরি করার চেষ্টা করছি

আমার আমার এক্স, ওয়াই ডেটা এবং প্রতিটি পয়েন্টের জন্য একটি পূর্ণসংখ্যার ট্যাগ মান যা আমি একটি অনন্য রঙের সাথে প্রতিনিধিত্ব করতে চাই

plt.scatter(x, y, c=tag)

সাধারণত ট্যাগটি 0-2 থেকে শুরু করে পূর্ণসংখ্যা হয় তবে সঠিক পরিসরটি পরিবর্তন হতে পারে

এখন পর্যন্ত আমি স্রেফ ডিফল্ট সেটিংস ব্যবহার করেছি

plt.colorbar()

যা ধারাবাহিকভাবে রঙ দেয় range আদর্শভাবে আমি এন আলাদা আলাদা রঙের একটি সেট চাই (এই উদাহরণে n = 20)। এর চেয়ে আরও ভাল হবে ধূসর বর্ণের উত্পাদন করতে 1 টির একটি মান মূল্য এবং 1-20 রঙিন হতে পারে।

আমি কিছু 'কুকবুক' স্ক্রিপ্ট পেয়েছি তবে সেগুলি খুব জটিল এবং আমি মনে হয় না যে এগুলি আপাতদৃষ্টিতে সহজ সমস্যা সমাধানের সঠিক উপায় think


4
না এই বা এই সাহায্য করেছিল?
ফ্রান্সেসকো মন্টেসানো

লিঙ্কগুলির জন্য ধন্যবাদ তবে ২ য় উদাহরণটি হ'ল আমি বোঝাচ্ছি যে অতিমাত্রায় জটিল অর্থ একটি (আপাতদৃষ্টিতে) তুচ্ছ কাজ সম্পাদন করার জন্য - 1 ম লিঙ্কটি দরকারী
বিএফ

4
আমি এই লিঙ্কটি একটি বিদ্যমান রঙিন মানচিত্রটিকে বিস্মৃত করতে
বলপয়েন্টবেইন

উত্তর:


95

আপনি আপনার স্ক্রেটারের জন্য সাধারণ হিসাবে বাউন্ডারিএনরম ব্যবহার করে আপনি খুব সহজেই একটি কাস্টম ডিসার্ট কালারবার তৈরি করতে পারেন। বিদ্বেষপূর্ণ বিট (আমার পদ্ধতিতে) 0 টি ধূসর হিসাবে শো আপ করছে।

চিত্রগুলির জন্য আমি প্রায়শই cmap.set_bad () ব্যবহার করি এবং আমার ডেটাগুলিকে একটি ছদ্মবেশী মুখোশযুক্ত অ্যারে রূপান্তর করি। এটি 0 ধূসর করা আরও সহজ হবে তবে আমি এটি স্ক্রেটার বা কাস্টম সিএম্যাপের সাথে কাজ করতে পারি না।

বিকল্প হিসাবে আপনি স্ক্র্যাচ থেকে আপনার নিজস্ব cmap তৈরি করতে পারেন, বা একটি বিদ্যমান পড়তে পারেন এবং কিছু নির্দিষ্ট এন্ট্রিগুলিকে ওভাররাইড করতে পারেন।

import numpy as np
import matplotlib as mpl
import matplotlib.pylab as plt

fig, ax = plt.subplots(1, 1, figsize=(6, 6))  # setup the plot

x = np.random.rand(20)  # define the data
y = np.random.rand(20)  # define the data
tag = np.random.randint(0, 20, 20)
tag[10:12] = 0  # make sure there are some 0 values to show up as grey

cmap = plt.cm.jet  # define the colormap
# extract all colors from the .jet map
cmaplist = [cmap(i) for i in range(cmap.N)]
# force the first color entry to be grey
cmaplist[0] = (.5, .5, .5, 1.0)

# create the new map
cmap = mpl.colors.LinearSegmentedColormap.from_list(
    'Custom cmap', cmaplist, cmap.N)

# define the bins and normalize
bounds = np.linspace(0, 20, 21)
norm = mpl.colors.BoundaryNorm(bounds, cmap.N)

# make the scatter
scat = ax.scatter(x, y, c=tag, s=np.random.randint(100, 500, 20),
                  cmap=cmap, norm=norm)

# create a second axes for the colorbar
ax2 = fig.add_axes([0.95, 0.1, 0.03, 0.8])
cb = plt.colorbar.ColorbarBase(ax2, cmap=cmap, norm=norm,
    spacing='proportional', ticks=bounds, boundaries=bounds, format='%1i')

ax.set_title('Well defined discrete colors')
ax2.set_ylabel('Very custom cbar [-]', size=12)

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

আমি ব্যক্তিগতভাবে মনে করি যে 20 টি বিভিন্ন রঙের সাথে এটি নির্দিষ্ট মানটি পড়তে কিছুটা শক্ত, তবে অবশ্যই এটি আপনার পক্ষে অবতীর্ণ।


এটি অনুমোদিত কিনা আমি নিশ্চিত নই, তবে আপনি কি আমার প্রশ্নটি এখানে দেখতে পারেন ?
vwos

7
plt.colorbar.ColorbarBaseত্রুটি নিক্ষেপ ব্যবহারmpl.colorbar.ColorbarBase
zeeshan khan

এই উত্তরের জন্য আপনাকে ধন্যবাদ, ডক থেকে সত্যই এটি মিস করুন। আমি এটি পার্সেন্টাইলের উইন্ড্রোজের জন্য স্থানান্তরিত করার চেষ্টা করেছি এবং রঙিন ম্যাপিংয়ের সাথে আমার একটি বাগ রয়েছে। কেমন জানি একটু অন্যরকম ব্যবহারের ক্ষেত্রে, কিন্তু এটা সুপারিশ করতে পারে যে এটা N-1মধ্যে cmap = mpl.colors.LinearSegmentedColormap.from_list('Custom cmap', cmaplist, cmap.N-1)। যদি রঙগুলি বিনের মধ্যে সমানভাবে বিতরণ না করা হয় এবং আপনার একটি বেড়া বাধা সমস্যা রয়েছে।
jlandercy

4
সমানভাবে বিতরণ করা ম্যাপিং পুনরুত্পাদন করার কোড এখানে:q=np.arange(0.0, 1.01, 0.1) cmap = mpl.cm.get_cmap('jet') cmaplist = [cmap(x) for x in q] cmap = mpl.colors.LinearSegmentedColormap.from_list('Custom cmap', cmaplist, len(q)-1) norm = mpl.colors.BoundaryNorm(q, cmap.N)
jlandercy

আমি সম্পর্কে নিশ্চিত নই N-1, আপনি হয়ত ঠিক বলেছেন তবে আমি এটি আমার উদাহরণ দিয়ে প্রতিলিপি করতে পারি না। আপনি এ ব্যবহার করে LinearSegmentedColormap(এবং এটির Nযুক্তি) এড়াতে পারেন ListedColormap। '13 এর পর থেকে ডক্সগুলি অনেক উন্নতি করেছে, উদাহরণস্বরূপ দেখুন: matplotlib.org/3.1.1/tutorials/colors/…
রাটার ক্যাসেস

65

আপনি এই উদাহরণটি অনুসরণ করতে পারেন :

#!/usr/bin/env python
"""
Use a pcolor or imshow with a custom colormap to make a contour plot.

Since this example was initially written, a proper contour routine was
added to matplotlib - see contour_demo.py and
http://matplotlib.sf.net/matplotlib.pylab.html#-contour.
"""

from pylab import *


delta = 0.01
x = arange(-3.0, 3.0, delta)
y = arange(-3.0, 3.0, delta)
X,Y = meshgrid(x, y)
Z1 = bivariate_normal(X, Y, 1.0, 1.0, 0.0, 0.0)
Z2 = bivariate_normal(X, Y, 1.5, 0.5, 1, 1)
Z = Z2 - Z1 # difference of Gaussians

cmap = cm.get_cmap('PiYG', 11)    # 11 discrete colors

im = imshow(Z, cmap=cmap, interpolation='bilinear',
            vmax=abs(Z).max(), vmin=-abs(Z).max())
axis('off')
colorbar()

show()

যা নিম্নলিখিত চিত্র উত্পাদন করে:

বেচারা_কন্টুর


14
cmap = cm.get_cmap ('jet', 20) তারপরে স্ক্র্যাটার (x, y, c = ট্যাগস, cmap = cmap) আমাকে সেখানে অংশ দেয়
mat ম্যাটপ্ল্লোব-এর

লিঙ্কটি নষ্ট হয়ে গেছে বলে মনে হচ্ছে, এফওয়াইআই।
কুইন কালভার

46

উপরের উত্তরগুলি ভাল, রঙবারে সঠিক টিক প্লেসমেন্ট না থাকলে এগুলি ভাল। আমি রঙের মাঝখানে টিকগুলি পছন্দ করি যাতে নম্বর -> রঙের ম্যাপিং আরও স্পষ্ট হয়। আপনি ম্যাথশো কলটির সীমা পরিবর্তন করে এই সমস্যাটি সমাধান করতে পারেন:

import matplotlib.pyplot as plt
import numpy as np

def discrete_matshow(data):
    #get discrete colormap
    cmap = plt.get_cmap('RdBu', np.max(data)-np.min(data)+1)
    # set limits .5 outside true range
    mat = plt.matshow(data,cmap=cmap,vmin = np.min(data)-.5, vmax = np.max(data)+.5)
    #tell the colorbar to tick at integers
    cax = plt.colorbar(mat, ticks=np.arange(np.min(data),np.max(data)+1))

#generate data
a=np.random.randint(1, 9, size=(10, 10))
discrete_matshow(a)

পৃথক রঙবার উদাহরণ


4
আমি একমত যে পৃথক রঙের ডেটা দেখার সময় সংশ্লিষ্ট রঙের মাঝখানে টিক স্থাপন করা খুব সহায়ক is আপনার দ্বিতীয় পদ্ধতিটি সঠিক। যাইহোক, আপনার প্রথম পদ্ধতিটি সাধারণভাবে ভুল : আপনি রঙগুলি বার্কের সাথে প্লেসমেন্টগুলি অসামঞ্জস্যযুক্ত মানগুলির সাথে টিকগুলি লেবেল করছেন। set_ticklabels(...)কেবলমাত্র লেবেল বিন্যাসকরণ (যেমন দশমিক সংখ্যা ইত্যাদি) নিয়ন্ত্রণ করতে ব্যবহার করা উচিত। যদি ডেটাটি সত্যই আলাদা হয় তবে আপনি কোনও সমস্যা লক্ষ্য করতে পারেন না। সিস্টেমে যদি শব্দ হয় (যেমন 2 -> 1.9), এই অসামঞ্জস্যপূর্ণ লেবেলিংয়ের ফলে একটি বিভ্রান্তিকর এবং ভুল রঙবার হবে।
ই ডেভিস

ই।, আমি মনে করি আপনি ঠিক বলেছেন যে সীমা পরিবর্তন করা সর্বোত্তম সমাধান তাই আমি অন্যটিকে সরিয়ে দিয়েছি - যদিও উভয়ই "শব্দ" ভালভাবে পরিচালনা করবে না। অবিচ্ছিন্ন ডেটা পরিচালনা করার জন্য কিছু সমন্বয় প্রয়োজন।
ben.dichter

39

রঙম্যাপের সীমার উপরে বা নীচে মান নির্ধারণ করতে, আপনি রঙিন মানচিত্রের পদ্ধতি set_overএবং set_underপদ্ধতিগুলি ব্যবহার করতে চাইবেন । আপনি যদি কোনও নির্দিষ্ট মান পতাকাঙ্কিত করতে চান তবে এটি মাস্ক করুন (অর্থাত একটি মুখোশযুক্ত অ্যারে তৈরি করুন), এবং set_badপদ্ধতিটি ব্যবহার করুন । (বেস রঙের মানচিত্র শ্রেণীর জন্য ডকুমেন্টেশনটি দেখুন: http://matplotlib.org/api/colors_api.html#matplotlib.colors.Corormap )

মনে হচ্ছে আপনি এরকম কিছু চান:

import matplotlib.pyplot as plt
import numpy as np

# Generate some data
x, y, z = np.random.random((3, 30))
z = z * 20 + 0.1

# Set some values in z to 0...
z[:5] = 0

cmap = plt.get_cmap('jet', 20)
cmap.set_under('gray')

fig, ax = plt.subplots()
cax = ax.scatter(x, y, c=z, s=100, cmap=cmap, vmin=0.1, vmax=z.max())
fig.colorbar(cax, extend='min')

plt.show()

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


সত্যিই ভাল - আমি সেট_উন্ডারটি ব্যবহার করার চেষ্টা করেছি তবে ভিমনকে অন্তর্ভুক্ত করেছিলাম তাই আমি মনে করি না এটি কিছু করছে
বিএফ

10

এই বিষয়টি ইতিমধ্যে ভালভাবে কভার করা হয়েছে তবে আমি আরও নির্দিষ্ট কিছু যুক্ত করতে চেয়েছিলাম: আমি নিশ্চিত হতে চেয়েছিলাম যে একটি নির্দিষ্ট মান সেই রঙের সাথে ম্যাপ করা হবে (কোনও রঙের সাথে নয়)।

এটি জটিল নয় তবে আমার কিছুটা সময় লেগেছিল, এটি অন্যকে আমার যতটা সময় না হারাতে সহায়তা করতে পারে :)

import matplotlib
from matplotlib.colors import ListedColormap

# Let's design a dummy land use field
A = np.reshape([7,2,13,7,2,2], (2,3))
vals = np.unique(A)

# Let's also design our color mapping: 1s should be plotted in blue, 2s in red, etc...
col_dict={1:"blue",
          2:"red",
          13:"orange",
          7:"green"}

# We create a colormar from our list of colors
cm = ListedColormap([col_dict[x] for x in col_dict.keys()])

# Let's also define the description of each category : 1 (blue) is Sea; 2 (red) is burnt, etc... Order should be respected here ! Or using another dict maybe could help.
labels = np.array(["Sea","City","Sand","Forest"])
len_lab = len(labels)

# prepare normalizer
## Prepare bins for the normalizer
norm_bins = np.sort([*col_dict.keys()]) + 0.5
norm_bins = np.insert(norm_bins, 0, np.min(norm_bins) - 1.0)
print(norm_bins)
## Make normalizer and formatter
norm = matplotlib.colors.BoundaryNorm(norm_bins, len_lab, clip=True)
fmt = matplotlib.ticker.FuncFormatter(lambda x, pos: labels[norm(x)])

# Plot our figure
fig,ax = plt.subplots()
im = ax.imshow(A, cmap=cm, norm=norm)

diff = norm_bins[1:] - norm_bins[:-1]
tickz = norm_bins[:-1] + diff / 2
cb = fig.colorbar(im, format=fmt, ticks=tickz)
fig.savefig("example_landuse.png")
plt.show()

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


এটি প্রতিলিপি দেওয়ার চেষ্টা করছিল, তবে কোডটি চালায় না কারণ 'tmp' অপরিজ্ঞাত। ল্যাম্বডা ফাংশনে 'পোস' কী রয়েছে তাও অস্পষ্ট। ধন্যবাদ!
জর্জ লিউ

পছন্দ করুন আমি একটি অনুলিপি / পেস্ট ভুল করেছি এবং এটি এখন fxed! কোডের স্নিপেট এখন চলছে! এটি সম্পর্কে posকেন আমি এখানে পুরোপুরি নিশ্চিত নই তবে এটি ফানকফর্মেটর () দ্বারা অনুরোধ করা হয়েছে ... সম্ভবত অন্য কেউ এটি সম্পর্কে আলোকিত করতে পারে!
এনজৌপি

7

আমি এই ধারণাগুলি তদন্ত করে চলেছি এবং এখানে আমার পাঁচটি সেন্টের মূল্য রয়েছে। এটি কল BoundaryNormকরা পাশাপাশি এবং এর normপক্ষে যুক্তি হিসাবে উল্লেখ করা এড়ানো যায় । তবে আমি দীর্ঘ-বায়ুযুক্ত কলটি সরিয়ে দেওয়ার কোনও উপায় খুঁজে পাই না ।scattercolorbarmatplotlib.colors.LinearSegmentedColormap.from_list

কিছু ব্যাকগ্রাউন্ড হ'ল ম্যাটপ্ল্লোলিব তথাকথিত গুণগত রঙিন ম্যাপগুলি সরবরাহ করে যা পৃথক পৃথক ডেটার সাথে ব্যবহারের উদ্দেশ্যে। Set1উদাহরণস্বরূপ, এর 9 টি সহজেই পৃথকযোগ্য রঙ রয়েছে এবং tab2020 টি রঙের জন্য ব্যবহার করা যেতে পারে। এই মানচিত্রগুলির সাহায্যে তাদের প্রথম এন বর্ণগুলি এন বিভাগগুলির সাথে স্ক্যাটার প্লটগুলিতে রঙ করা প্রাকৃতিক হতে পারে, যেমন নীচের উদাহরণটি করে। উদাহরণস্বরূপ এ্যাপ্রোপ্রাইটিলি লেবেলযুক্ত এন ডিসক্রিট রঙগুলির সাথে একটি কালারবার তৈরি করা হয়।

import matplotlib, numpy as np, matplotlib.pyplot as plt
n = 5
from_list = matplotlib.colors.LinearSegmentedColormap.from_list
cm = from_list(None, plt.cm.Set1(range(0,n)), n)
x = np.arange(99)
y = x % 11
z = x % n
plt.scatter(x, y, c=z, cmap=cm)
plt.clim(-0.5, n-0.5)
cb = plt.colorbar(ticks=range(0,n), label='Group')
cb.ax.tick_params(length=0)

যা নীচে চিত্র উত্পাদন করে। সেই রঙের মানচিত্রের প্রথম রঙগুলি নির্দিষ্ট nকরার জন্য কলটিতে , এবং কলগুলিতে শেষ রঙগুলির সাথে মানচিত্র তৈরি করতে নির্দিষ্ট করে (ডিফল্টটি 256)। এর সাথে ডিফল্ট রঙিন মানচিত্র হিসাবে সেট করার জন্য , আমি এটির একটি নাম দেওয়া এবং এটি নিবন্ধকরণ করা প্রয়োজন বলে মনে হয়েছে, যেমন:Set1nnfrom_listncmplt.set_cmap

cm = from_list('Set15', plt.cm.Set1(range(0,n)), n)
plt.cm.register_cmap(None, cm)
plt.set_cmap(cm)
...
plt.scatter(x, y, c=z)

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


1

আমি মনে করি আপনি রঙগুলি দেখতে চান your আপনার রঙিন মানচিত্র উত্পন্ন করতে তালিকাভুক্ত রঙিন মানচিত্র , বা আপনার যদি কেবল একটি স্ট্যাটিক রঙিন্যাপ প্রয়োজন হয় তবে আমি এমন অ্যাপ্লিকেশনটিতে কাজ করছি যা সহায়তা করতে পারে।


এটি দেখতে দুর্দান্ত লাগছে, সম্ভবত আমার প্রয়োজনের জন্য ওভারকিল - আপনি কি কোনও বিদ্যমান রঙিন মানচিত্রে ধূসর মান ট্যাগ করার কোনও উপায়ের পরামর্শ দিতে পারেন? যাতে 0 টি মান ধূসর হয় এবং অন্যগুলি রঙ হিসাবে আসে?
বিএফএফ

@ হায়ট আপনার ওয়াইয়ের মানগুলির উপর ভিত্তি করে আরজিবি অ্যারে রঙ_লিস্ট তৈরি এবং তালিকাভুক্ত কলরম্যাপে পাস করার বিষয়ে কী? আপনি color_list [y == value_to_tag] = ধূসর_রঙ দিয়ে একটি মান ট্যাগ করতে পারেন।
ক্রিসি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.