如何在Matplotlib PatchCollection中循环颜色?

lawou6xi  于 2023-01-05  发布在  其他
关注(0)|答案(2)|浏览(148)

我尝试自动为PatchCollection中的每个Patch指定一个颜色Map表(如tab20)中的颜色。

from matplotlib.collections import PatchCollection
import matplotlib.pyplot as plt

fig, ax = plt.subplots(figsize=(5,5))
coords = [
    (0, 0),
    (1, 2),
    (1, 3),
    (2, 2),
]
patches = [plt.Circle(coords[i], 0.1) for i in range(len(coords))]
patch_collection = PatchCollection(patches, cmap='tab20', match_original=True)
ax.add_collection(patch_collection)

ax.set_xlim(-1, 3)
ax.set_ylim(-1, 4)
plt.axis('equal')

但是上面的代码是用相同的颜色画每个圆的,颜色怎么循环呢?

ddrv8njm

ddrv8njm1#

这里我对tab20色彩Map表进行了 * 采样 *,因此RGBA数组cmap.colors正好有20个不同的条目,然后我将此RGBA数组赋给每个集合都接受的关键字参数facecolors
不仅仅是为了美观,我还添加了一个颜色Map表,这样就可以识别圆圈的绘制顺序。

from matplotlib.collections import PatchCollection
import matplotlib.pyplot as plt
from numpy.random import rand, seed

seed(20230104)
N = 20
coords = rand(N,2)*[2,1.2]
cmap = plt.get_cmap('tab20', N)

fig, ax = plt.subplots()
patches = [plt.Circle(coord, 0.06) for coord in coords]
# use facecolors=...
collection = PatchCollection(patches, facecolors=cmap.colors[:N-1])
ax.add_collection(collection)
cb = plt.colorbar(plt.cm.ScalarMappable(plt.Normalize(-0.5, N-0.5), cmap))
cb.set_ticks(range(N), labels=('%02d'%(n+1) for n in range(N)))
ax.autoscale(collection)
ax.set_aspect(1)
  • 过头版 *

from matplotlib.collections import PatchCollection
import matplotlib.pyplot as plt
from numpy.random import rand, seed

seed(20230104)
N = 20
coords = rand(N, 2) * [2, 1.2]
cmap = plt.get_cmap("tab20", N)
patches = (plt.Circle(coord, 0.06) for coord in coords)

fig, ax = plt.subplots()
im = ax.add_collection(
    PatchCollection(
        patches,
        facecolors=cmap.colors,
        edgecolors="w",
        linewidth=2,
        cmap=cmap,
        norm=plt.Normalize(-0.50, N - 0.50),
    )
)

cb = plt.colorbar(
    im,
    location="bottom",
    fraction=0.05,
    aspect=50,
    drawedges=True,
)
cb.set_ticks(range(N), labels=("%02d" % (n + 1) for n in range(N)))
cb.dividers.set_color(ax._facecolor)
cb.dividers.set_linewidth(3)

ax.autoscale()
ax.set_aspect(1)
i86rm4rw

i86rm4rw2#

这将从选定色彩Map表中的固定颜色子集为每个面片指定颜色,并根据需要重复:

from matplotlib.collections import PatchCollection
import matplotlib.pyplot as plt

num_col = 3
cmap = plt.cm.tab20

fig, ax = plt.subplots(figsize=(5,5))
coords = [
    (0, 0),
    (1, 2),
    (1, 3),
    (2, 2),
]

patches = [plt.Circle(coords[i], 0.1) for i in range(len(coords))]
patch_collection = PatchCollection(patches, facecolor=cmap.colors[0:num_col])
ax.add_collection(patch_collection)

ax.set_xlim(-1, 3)
ax.set_ylim(-1, 4)
plt.axis('equal')

输出:

这将通过使用numpy生成随机数列表,然后使用面片对象set_array方法,从选定的颜色贴图中提供随机颜色:

from matplotlib.collections import PatchCollection
import matplotlib.pyplot as plt
import numpy as np

fig, ax = plt.subplots(figsize=(5,5))
coords = [
    (0, 0),
    (1, 2),
    (1, 3),
    (2, 2),
]
patches = [plt.Circle(coords[i], 0.1) for i in range(len(coords))]
color_vals = np.random.rand(len(patches))
patch_collection = PatchCollection(patches, cmap='tab20', match_original=True)
patch_collection.set_array(color_vals)
ax.add_collection(patch_collection)

ax.set_xlim(-1, 3)
ax.set_ylim(-1, 4)
plt.axis('equal')

输出:

我不认为match_original=True是必要的,因为你想改变原始补丁的默认颜色。我相信还有其他方法可以做到这一点。这篇文章很有帮助:setting color range in matplotlib patchcollection

相关问题