Ваш вопрос не очень понятен. Вот обновленная версия вашего кода:
# EDITED, see below
Arc4
заполняет другую сторону эллипса. Это то, что вы ожидали?
Я также добавил пример использования карты цветов. Существует широкий диапазон цветовых карт , многие из которых варьируются от 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
, если вы этого не хотите). Тем не менее, я не вижу, как вы можете достичь того, что вы хотите без «патча». Извините.
Надеюсь, что эта помощь.
Редактировать 2
После уточнений вот новая версия:
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()
И полученное изображение:
Как это работает:
- путем рисования нескольких эллипсов, идеально наложенных на «базовый». Это гарантирует, что все ваши области идеально подходят внутри вашего базового эллипса (ни один из них не может охватить)
- путем определения обтравочных контуров, которые будут обрезать / обрезать эллипсы, чтобы показать только их часть,Эти обтравочные контуры должны пересекать (или, по крайней мере, следовать) границы базового эллипса, чтобы он был заполнен (поэтому я меняю ваш Arc3, используя центр эллипса и размеры, иначе на границе было белое пространствовнутри эллипса, как вы можете видеть на первом рисунке).
Вы были не так далеко со своей последней попыткой. Чтобы стилизовать ваши области, вы должны применить стиль к вашим базовым эллипсам (перечисленным в списке areas
в моем коде), а не к вашим путям отсечения (перечисленным в списке clips
в моем коде). Оба списка areas
и clips
должны иметь одинаковую длину! Вы можете добавить больше областей и обтравочных контуров, если хотите, чтобы в ваших эллипсах было больше подобластей.
Кстати, я вижу ваш обновленный вопрос и ваши требования, чтобы области не перекрывались. Это потребует больше работы. Вы можете добиться этого, построив более сложный путь отсечения, используя модуль matplotlip.path
.