绘制许多彩色矩形
Plotting Many Colorful Rectangles
我有想要绘制的数据。我认为最好的方法是使用一系列矩形。我希望每个矩形跨越宽度 delta_t(每个时间间隔相同)和高度 delta_f(频率间隔可能不同)并且每个矩形的颜色由 log(z) 给出. This example 似乎有一些提示,但我无法将它们放在一起。这是我到目前为止得到的
from matplotlib.collections import PatchCollection
from matplotlib.patches import Rectangle
def make_rectangle(t_min, f_min, delta_t, delta_f, z):
return Rectangle(xy = (t_min, f_min), width = delta_t, height = delta_f, edgecolor = 'k')
timeex=[0,1,2,3,4]
frequencyex=[0,.1,1,10,100]
zex=[[1,1.2,1.1,1.5,1.6], [.01,120,.11,1.6,1.5],
[.1,.12,1.1e-6,15,16], [1,1.2,1.1,1.5,1.6], [.01,120,.11,1.6,1.5]]
tiles = []
for i in range(len(timeex) - 1):
t_min = timeex[i]
f_min = frequencyex[i]
t_max = timeex[i + 1]
f_max = frequencyex[i + 1]
for j in range(len(zex[i])):
rect = make_rectangle(t_min, f_min, t_max - t_min, f_max - f_min, zex[i][j])
tiles.append(rect)
fig = plt.figure()
ax = fig.add_subplot(111)
p = PatchCollection(tiles, cmap=plt.cm.jet)
ax.add_collection(p)
fig.colorbar(p)
fig.show()
这将生成附加图像。该图在某些方面有所欠缺:矩形高度不是我所期望的。对轴进行对数缩放没有帮助。我不知道如何对矩形进行对数着色。我想在 10e-6 和 10 之间标准化色阶。
我设想的最终产品看起来有点像显示的输出 here。
我正在使用 Python 3.6 和 matplotlib 3.3.2。
编辑:下面的绝妙答案解决了我的大部分绘图问题。我用循环转过身来,但我很快就解决了。感谢您的帮助。
我添加或更改了一些内容以获得此:
将 y 轴刻度更改为对数。
手动更改了 x 和 y 限制,以便矩形适合。
为您的 PatchCollection
指定了一个 norm
,以便它知道如何将值转换为颜色。没有这个,你只能使用不是你想要的0-1范围。
指定了 PatchCollection
的 array
以便它知道 哪个 值要转换为颜色。为此,我们存储提供的 zex[i][j]
值列表。无需向 make_rectangle
提供这些值(无论如何它们都未被使用)。
理论上,您可以根据数据自动计算范数的最小值和最大值以及斧头的极限。在这里,我采用了您在 OP (1e-6, 10) 和手动限制中给出的规范。
# Imports.
import matplotlib.pyplot as plt
from matplotlib.collections import PatchCollection
from matplotlib.patches import Rectangle
from matplotlib.colors import LogNorm
import numpy as np
def make_rectangle(t_min, f_min, delta_t, delta_f):
return Rectangle(xy = (t_min, f_min), width = delta_t, height = delta_f, edgecolor = 'k')
timeex = [0, 1, 2, 3, 4]
frequencyex = [0, 0.1, 1, 10, 100]
zex = [[1, 1.2, 1.1, 1.5, 1.6],
[0.01, 120, 0.11, 1.6, 1.5],
[0.1, 0.12, 1.1e-6, 15, 16],
[1, 1.2, 1.1, 1.5, 1.6],
[0.01, 120, 0.11, 1.6, 1.5]]
tiles = []
values = []
for i in range(len(timeex) - 1):
t_min = timeex[i]
f_min = frequencyex[i]
t_max = timeex[i + 1]
f_max = frequencyex[i + 1]
for j in range(len(zex[i])):
rect = make_rectangle(t_min, f_min, t_max - t_min, f_max - f_min)
tiles.append(rect)
values.append(zex[i][j])
# Create figure and ax.
fig = plt.figure()
ax = fig.add_subplot(111)
# Normalize entry values to 0-1 for the colormap, and add the colorbar.
norm = LogNorm(vmin=1e-6, vmax=10)
p = PatchCollection(tiles, cmap=plt.cm.jet, norm=norm, match_original=True) # You need `match_original=True` otherwise you lose the black edgecolor.
fig.colorbar(p)
ax.add_collection(p)
# Set the "array" of the patch collection which is in turn used to give the appropriate colors.
p.set_array(np.array(values))
# Scale the axis so that the rectangles show properly. This can be done automatically
# from the data of the patches but I leave this to you.
ax.set_yscale("log")
ax.set_xlim(0, 8)
ax.set_ylim(0, 100)
fig.show()
我有想要绘制的数据。我认为最好的方法是使用一系列矩形。我希望每个矩形跨越宽度 delta_t(每个时间间隔相同)和高度 delta_f(频率间隔可能不同)并且每个矩形的颜色由 log(z) 给出. This example 似乎有一些提示,但我无法将它们放在一起。这是我到目前为止得到的
from matplotlib.collections import PatchCollection
from matplotlib.patches import Rectangle
def make_rectangle(t_min, f_min, delta_t, delta_f, z):
return Rectangle(xy = (t_min, f_min), width = delta_t, height = delta_f, edgecolor = 'k')
timeex=[0,1,2,3,4]
frequencyex=[0,.1,1,10,100]
zex=[[1,1.2,1.1,1.5,1.6], [.01,120,.11,1.6,1.5],
[.1,.12,1.1e-6,15,16], [1,1.2,1.1,1.5,1.6], [.01,120,.11,1.6,1.5]]
tiles = []
for i in range(len(timeex) - 1):
t_min = timeex[i]
f_min = frequencyex[i]
t_max = timeex[i + 1]
f_max = frequencyex[i + 1]
for j in range(len(zex[i])):
rect = make_rectangle(t_min, f_min, t_max - t_min, f_max - f_min, zex[i][j])
tiles.append(rect)
fig = plt.figure()
ax = fig.add_subplot(111)
p = PatchCollection(tiles, cmap=plt.cm.jet)
ax.add_collection(p)
fig.colorbar(p)
fig.show()
这将生成附加图像。该图在某些方面有所欠缺:矩形高度不是我所期望的。对轴进行对数缩放没有帮助。我不知道如何对矩形进行对数着色。我想在 10e-6 和 10 之间标准化色阶。
我设想的最终产品看起来有点像显示的输出 here。
我正在使用 Python 3.6 和 matplotlib 3.3.2。
编辑:下面的绝妙答案解决了我的大部分绘图问题。我用循环转过身来,但我很快就解决了。感谢您的帮助。
我添加或更改了一些内容以获得此:
将 y 轴刻度更改为对数。
手动更改了 x 和 y 限制,以便矩形适合。
为您的
PatchCollection
指定了一个norm
,以便它知道如何将值转换为颜色。没有这个,你只能使用不是你想要的0-1范围。指定了
PatchCollection
的array
以便它知道 哪个 值要转换为颜色。为此,我们存储提供的zex[i][j]
值列表。无需向make_rectangle
提供这些值(无论如何它们都未被使用)。
理论上,您可以根据数据自动计算范数的最小值和最大值以及斧头的极限。在这里,我采用了您在 OP (1e-6, 10) 和手动限制中给出的规范。
# Imports.
import matplotlib.pyplot as plt
from matplotlib.collections import PatchCollection
from matplotlib.patches import Rectangle
from matplotlib.colors import LogNorm
import numpy as np
def make_rectangle(t_min, f_min, delta_t, delta_f):
return Rectangle(xy = (t_min, f_min), width = delta_t, height = delta_f, edgecolor = 'k')
timeex = [0, 1, 2, 3, 4]
frequencyex = [0, 0.1, 1, 10, 100]
zex = [[1, 1.2, 1.1, 1.5, 1.6],
[0.01, 120, 0.11, 1.6, 1.5],
[0.1, 0.12, 1.1e-6, 15, 16],
[1, 1.2, 1.1, 1.5, 1.6],
[0.01, 120, 0.11, 1.6, 1.5]]
tiles = []
values = []
for i in range(len(timeex) - 1):
t_min = timeex[i]
f_min = frequencyex[i]
t_max = timeex[i + 1]
f_max = frequencyex[i + 1]
for j in range(len(zex[i])):
rect = make_rectangle(t_min, f_min, t_max - t_min, f_max - f_min)
tiles.append(rect)
values.append(zex[i][j])
# Create figure and ax.
fig = plt.figure()
ax = fig.add_subplot(111)
# Normalize entry values to 0-1 for the colormap, and add the colorbar.
norm = LogNorm(vmin=1e-6, vmax=10)
p = PatchCollection(tiles, cmap=plt.cm.jet, norm=norm, match_original=True) # You need `match_original=True` otherwise you lose the black edgecolor.
fig.colorbar(p)
ax.add_collection(p)
# Set the "array" of the patch collection which is in turn used to give the appropriate colors.
p.set_array(np.array(values))
# Scale the axis so that the rectangles show properly. This can be done automatically
# from the data of the patches but I leave this to you.
ax.set_yscale("log")
ax.set_xlim(0, 8)
ax.set_ylim(0, 100)
fig.show()