matplotlib 在楔形图块(饼图)中保留纵横比
matplotlib preserve aspect ratio in Wedge patches (pie charts)
我想在特定位置绘制彩色饼图而不扭曲其圆形纵横比。我正在使用 Wedge 补丁,因为我找不到更好的解决方案。这是代码
import matplotlib.pyplot as plt
import numpy as np
from matplotlib import patches, collections
fig, axes = plt.subplots()
for i in range(20):
x = np.random.uniform(low=0, high=1, size=10).cumsum()
axes.scatter(x=x, y=np.repeat(i, x.shape[0]), c='gray', s=1)
pies = []
N = 4
cmap = plt.cm.get_cmap("hsv", N + 1)
colors = list(map(cmap, range(N)))
print(colors)
for i in range(2, 2 + N):
thetas = np.linspace(0, 360, num=i)
assert len(thetas) - 1 <= len(colors)
for theta1, theta2, c in zip(thetas[:-1], thetas[1:], colors):
wedge = patches.Wedge((i, i), r=i / 10, theta1=theta1, theta2=theta2,
color=c)
pies.append(wedge)
axes.add_collection(collections.PatchCollection(pies,
match_original=True))
plt.show()
如何保持饼图的纵横比?设置 axes.set_aspect("equal")
不是一个选项,因为当我有更多数据点时,它会完全压缩绘图。
我一直在查看 how to draw circles and preserve the aspect ratio 但这里无法采用解决方案 - 我正在绘制 Wedges/pie 图表,而不是圆圈。
我也看了 matplotlib transforms 但也没有找到答案。
当我设置 set_aspect('equal')
:
时对我来说效果很好
我觉得 y-range 比 x-range 长,所以图片变窄了。
如果您将 y_lim 设置在 0 和小于 y_max 的数字之间,您会看得更清楚:
import matplotlib.pyplot as plt
import numpy as np
from matplotlib import patches, collections
fig, axes = plt.subplots()
for i in range(20):
x = np.random.uniform(low=0, high=1, size=10).cumsum()
axes.scatter(x=x, y=np.repeat(i, x.shape[0]), c='gray', s=1)
pies = []
N = 4
cmap = plt.cm.get_cmap("hsv", N + 1)
colors = list(map(cmap, range(N)))
print(colors)
for i in range(2, 2 + N):
thetas = np.linspace(0, 360, num=i)
assert len(thetas) - 1 <= len(colors)
for theta1, theta2, c in zip(thetas[:-1], thetas[1:], colors):
wedge = patches.Wedge((i, i), r=i / 10, theta1=theta1, theta2=theta2,
color=c)
pies.append(wedge)
axes.add_collection(collections.PatchCollection(pies,
match_original=True))
axes.set_aspect('equal')
axes.set_ylim(0,7.5)
plt.show()
我尝试了同样的事情,而 matplotlib 确实没有尝试让这对你来说很容易,但我找到了一个你应该能够使用的解决方案。
您需要将中心与楔形分开,并将它们作为偏移量添加到 PatchCollection 中。然后你可以对偏移量(transOffset)和形状(transform)应用不同的变换。
注意我已经更改了 r 值(半径)。此值不再位于数据坐标中,因此无论缩放多少,它都应始终保持相同大小,但它太小以至于无法在 i/10
.
处看到
from matplotlib import patches, collections, transforms
offsets = []
for i in range(2, 2 + N):
thetas = np.linspace(0, 360, num=i)
assert len(thetas) - 1 <= len(colors)
for theta1, theta2, c in zip(thetas[:-1], thetas[1:], colors):
wedge = patches.Wedge((0, 0), r=10, theta1=theta1, theta2=theta2,
color=c)
offsets.append((i, i))
pies.append(wedge)
coll = collections.PatchCollection(
pies, match_original=True, offsets=offsets,
transform=transforms.IdentityTransform(),
transOffset=axes.transData
)
我想在特定位置绘制彩色饼图而不扭曲其圆形纵横比。我正在使用 Wedge 补丁,因为我找不到更好的解决方案。这是代码
import matplotlib.pyplot as plt
import numpy as np
from matplotlib import patches, collections
fig, axes = plt.subplots()
for i in range(20):
x = np.random.uniform(low=0, high=1, size=10).cumsum()
axes.scatter(x=x, y=np.repeat(i, x.shape[0]), c='gray', s=1)
pies = []
N = 4
cmap = plt.cm.get_cmap("hsv", N + 1)
colors = list(map(cmap, range(N)))
print(colors)
for i in range(2, 2 + N):
thetas = np.linspace(0, 360, num=i)
assert len(thetas) - 1 <= len(colors)
for theta1, theta2, c in zip(thetas[:-1], thetas[1:], colors):
wedge = patches.Wedge((i, i), r=i / 10, theta1=theta1, theta2=theta2,
color=c)
pies.append(wedge)
axes.add_collection(collections.PatchCollection(pies,
match_original=True))
plt.show()
如何保持饼图的纵横比?设置 axes.set_aspect("equal")
不是一个选项,因为当我有更多数据点时,它会完全压缩绘图。
我一直在查看 how to draw circles and preserve the aspect ratio 但这里无法采用解决方案 - 我正在绘制 Wedges/pie 图表,而不是圆圈。
我也看了 matplotlib transforms 但也没有找到答案。
当我设置 set_aspect('equal')
:
我觉得 y-range 比 x-range 长,所以图片变窄了。
如果您将 y_lim 设置在 0 和小于 y_max 的数字之间,您会看得更清楚:
import matplotlib.pyplot as plt
import numpy as np
from matplotlib import patches, collections
fig, axes = plt.subplots()
for i in range(20):
x = np.random.uniform(low=0, high=1, size=10).cumsum()
axes.scatter(x=x, y=np.repeat(i, x.shape[0]), c='gray', s=1)
pies = []
N = 4
cmap = plt.cm.get_cmap("hsv", N + 1)
colors = list(map(cmap, range(N)))
print(colors)
for i in range(2, 2 + N):
thetas = np.linspace(0, 360, num=i)
assert len(thetas) - 1 <= len(colors)
for theta1, theta2, c in zip(thetas[:-1], thetas[1:], colors):
wedge = patches.Wedge((i, i), r=i / 10, theta1=theta1, theta2=theta2,
color=c)
pies.append(wedge)
axes.add_collection(collections.PatchCollection(pies,
match_original=True))
axes.set_aspect('equal')
axes.set_ylim(0,7.5)
plt.show()
我尝试了同样的事情,而 matplotlib 确实没有尝试让这对你来说很容易,但我找到了一个你应该能够使用的解决方案。
您需要将中心与楔形分开,并将它们作为偏移量添加到 PatchCollection 中。然后你可以对偏移量(transOffset)和形状(transform)应用不同的变换。
注意我已经更改了 r 值(半径)。此值不再位于数据坐标中,因此无论缩放多少,它都应始终保持相同大小,但它太小以至于无法在 i/10
.
from matplotlib import patches, collections, transforms
offsets = []
for i in range(2, 2 + N):
thetas = np.linspace(0, 360, num=i)
assert len(thetas) - 1 <= len(colors)
for theta1, theta2, c in zip(thetas[:-1], thetas[1:], colors):
wedge = patches.Wedge((0, 0), r=10, theta1=theta1, theta2=theta2,
color=c)
offsets.append((i, i))
pies.append(wedge)
coll = collections.PatchCollection(
pies, match_original=True, offsets=offsets,
transform=transforms.IdentityTransform(),
transOffset=axes.transData
)