我有一个ellipse
,我想用不同部分的颜色固定 fill
。为此,我使用了arcs
补丁。我目前正在绘制多个arcs
,并使用zorder
覆盖适当的arcs
。
主要问题是我无法固定填充arc
补丁,并且它们不能整齐地填充ellipse
。如果这些区域也没有重叠,那就太好了。我可以使用透明度参数。
import matplotlib.pyplot as plt
import matplotlib as mpl
import math
fig, ax = plt.subplots(figsize = (8,5))
ax.grid(False)
ax.set_xlim(-85,85)
ax.set_ylim(-70,70)
Arc1_xy = -68, 0
Arc2_xy = -48,0
Arc3_xy = 15, 0
Arc4_xy = 68, 0
Arc5_xy = 48,0
Arc6_xy = -15, 0
E_xy = 0,0
angle = math.degrees(math.acos(2/9.15))
Arc1 = mpl.patches.Arc(Arc1_xy, 75, 92, angle = 360, theta2 = angle, theta1 = 360-angle, color = 'w', lw = 1, alpha = 1, hatch = 'oooooo', zorder = 3)
Arc2 = mpl.patches.Arc(Arc2_xy, 64, 94, angle = 180, theta2 = angle, theta1 = 360-angle, color = 'w', lw = 1, alpha = 1, hatch = 'oooooo', zorder = 3)
Arc3 = mpl.patches.Arc(Arc3_xy, 190, 132, angle = -180, theta2 = angle, theta1 = 360-angle, color = 'w', lw = 1, alpha = 1, hatch = 'oooooo', zorder = 1)
Arc4 = mpl.patches.Arc(Arc4_xy, 75, 92, angle = 180, theta2 = angle, theta1 = 360-angle, color = 'w', lw = 1, alpha = 1, hatch = 'oooooo', zorder = 3)
Arc5 = mpl.patches.Arc(Arc5_xy, 64, 94, angle = 0, theta2 = angle, theta1 = 0-angle, color = 'w', lw = 1, alpha = 1, hatch = 'oooooo', zorder = 3)
Arc6 = mpl.patches.Arc(Arc6_xy, 190, 132, angle = 360, theta2 = angle, theta1 = 360-angle, color = 'w', lw = 1, alpha = 1, hatch = 'oooooo', zorder = 1)
Ellipse = mpl.patches.Ellipse(E_xy, 160, 130, lw = 1, color = 'white', alpha = 1, fill = False)
ax.add_patch(Arc1)
ax.add_patch(Arc2)
ax.add_patch(Arc3)
ax.add_patch(Arc4)
ax.add_patch(Arc5)
ax.add_patch(Arc6)
ax.add_patch(Ellipse)
Arc1.set_color('green')
Arc2.set_color('green')
Arc3.set_color('blue')
Arc4.set_color('red')
Arc5.set_color('red')
Arc6.set_color('purple')
主要问题是我想固定填充ellipse
中不同颜色的部分。理想情况下,这些部分不会重叠,因此我可以使用alpha
。同样,arcs
也不完全适合ellipse
。
答案 0 :(得分:1)
您的问题不是很清楚。这是您代码的更新版本:
# EDITED, see below
Arc4
填充椭圆的另一侧。是您所期望的吗?
我还添加了一个有关如何使用颜色图的示例。 range of colormaps范围很广, 其中许多的范围是0到255(您可以将其归一化为0.0-1.0)。
另一种解决方案是绘制重叠的椭圆,并使用clip_path属性仅显示所需的部分。
要完美地拟合椭圆,您必须计算出适合其的圆弧,这可能很困难(也许有一些不错的数学技巧可以实现,但这是我所不知道的)。因此,我最好的选择是绘制相同大小的多个椭圆并使用剪切路径。
import matplotlib.pyplot as plt
import matplotlib as mpl
def main():
fig, ax = plt.subplots(figsize = (8,5))
ax.grid(False)
ax.set_xlim(-80,80)
ax.set_ylim(-70,70)
Arc1_xy = -68, 0
Arc3_xy = 15, 0
E_xy = 0,0
# Use a predefined colormap
colormap = plt.cm.get_cmap("Set1")
# Draw multiple ellipses with different colors and hatching style. All are perfectly superposed
ellipse = mpl.patches.Ellipse( # Base one, with big black line for reference, in background (zorder=0)
E_xy, 160, 130,
lw = 2, color = 'k', fill=False, zorder=0)
area1 = mpl.patches.Ellipse( # A second one, above the base one, using a color from colormap
E_xy, 160, 130,
lw=1, # Just to highlight that we perfectly fit the base ellipse
color = colormap(0), hatch='o', fill=False, zorder=1)
area2 = mpl.patches.Ellipse( # Third one, above the others
E_xy, 160, 130,
lw=1, # Just to highlight that we perfectly fit the base ellipse
color = colormap(1), hatch='..', fill=False, zorder=2)
# Add more if you want more "sub-areas" in your base ellipse
# Define some clipping paths
clip1 = mpl.patches.Ellipse(
Arc1_xy, 75, 92,
fill=False,
ls=":" # Just to highlight it but you should remove it
# visible=False # We do not need to display it, just to use it for clipping
)
clip2 = mpl.patches.Ellipse(
Arc3_xy, 190, 132, angle = -180,
fill=False,
ls=":" # Just to highlight it but you should remove it
# visible=False # We do not need to display it, just to use it for clipping
)
# Add all your components to your axe
ax.add_patch(ellipse)
ax.add_patch(area1)
ax.add_patch(area2)
ax.add_patch(clip1)
ax.add_patch(clip2)
# Clip the sub-areas with your clipping paths
area1.set_clip_path(clip2)
area2.set_clip_path(clip1)
plt.show()
if __name__ == '__main__':
main()
这将吸引您:
您说要“固定填充椭圆。不使用色块”。要实心填充,只需使用您所在区域的fill
和color
参数即可(如果不需要,请删除hatch
)。但是,我看不到没有“补丁”如何可以实现想要的目标。抱歉。
希望获得帮助。
经过澄清后,这里是一个新版本:
import math
import matplotlib.pyplot as plt
import matplotlib as mpl
def main():
fig, ax = plt.subplots(figsize=(8, 5))
ax.grid(False)
ax.set_xlim(-85, 85)
ax.set_ylim(-70, 70)
Arc1_xy = -68, 0
E_xy = 0, 0
# Use a predefined colormap
colormap = plt.cm.get_cmap("Set1")
# Draw multiple ellipses with different colors and style. All are perfectly superposed
ellipse = mpl.patches.Ellipse( # Base one, with big black line for reference
E_xy, 160, 130,
lw=2, color='k', fill=False, zorder=100)
# Ellipses for your sub-areas.
# Add more if you want more areas
# Apply the style of your areas here (colors, alpha, hatch, etc.)
areas = [
mpl.patches.Ellipse(
E_xy, 160, 130, # Perfectly fit your base ellipse
color=colormap(i), fill=True, alpha=0.5, # Add some style, fill, color, alpha
zorder=i)
for i in range(4) # Here, we have 4 areas
]
# Define some clipping paths
# One for each area
clips = [
mpl.patches.Arc( # One covering right half of your ellipse
E_xy, 160, 130, theta1=-90, theta2=90,
visible=False # We do not need to display it, just to use it for clipping
),
mpl.patches.Arc( # One covering left half of your ellipse
tuple([-x for x in E_xy]), 160, 130, theta1=90, theta2=-90,
visible=False # We do not need to display it, just to use it for clipping
),
mpl.patches.Ellipse( # A small area on the left
Arc1_xy, 75, 92,
visible=False # We do not need to display it, just to use it for clipping
),
mpl.patches.Ellipse( # A small area on the right
tuple([-x for x in Arc1_xy]), 75, 92,
visible=False # We do not need to display it, just to use it for clipping
)
]
# Add all your components to your axe
ax.add_patch(ellipse)
for area, clip in zip(areas, clips):
ax.add_patch(area)
ax.add_patch(clip)
area.set_clip_path(clip) # Use clipping paths to clip you areas
plt.show()
if __name__ == '__main__':
main()
它是如何工作的:
您最近一次尝试并没有那么远。要为您的区域设置样式,您必须将样式应用于基本椭圆(在我的代码的areas
列表中列出),而不是在剪切路径(在我的代码的clips
列表中列出)中应用。 areas
和clips
这两个列表的长度必须相同!如果您想在椭圆中添加更多子区域,则可以自行决定添加更多区域和更多剪切路径。
顺便说一句,我看到了您更新的问题和您对使区域不重叠的要求。这将需要更多的工作。您可以使用matplotlip.path
模块通过构建更复杂的剪切路径来实现。