2013-03-10 2 views
6

Я хотел бы разместить половину черного, полу белого круга радиуса R в начале участка matplotlib. Я знаю, что существует Circle class, но я не знаю, как указать, что левая половина круга должна быть белой, а правая половина - черной. (Идеальное решение позволило бы мне определить ориентацию круга - например, я должен был бы повернуть его так, чтобы, например, верхняя часть могла быть белой и нижней черной).Matplotlib half black и half white circle

+0

Вы должны быть в состоянии сделать это с двумя 'Wedge's, но у меня возникают проблемы при получении вещей, чтобы работать должным образом ... –

+0

@JoeKington - Ой-ой. Если вам не удастся заставить его работать, это немного обескураживает для меня ;-) (я видел, что некоторые из ваших matplotlib работают здесь, на SO ... Это очень впечатляет) – mgilson

+0

Спасибо! Оказывается, я просто делал что-то глупое. Два клина отлично работают, если вы не добавляете случайные опечатки к вещам! –

ответ

14

Самый простой способ - использовать два Wedge s. (Это не автоматически изменять масштаб осей, но это легко добавить, если вы хотите.)

Как простой пример:

import matplotlib.pyplot as plt 
from matplotlib.patches import Wedge 

def main(): 
    fig, ax = plt.subplots() 
    dual_half_circle((0.5, 0.5), radius=0.3, angle=90, ax=ax) 
    ax.axis('equal') 
    plt.show() 

def dual_half_circle(center, radius, angle=0, ax=None, colors=('w','k'), 
        **kwargs): 
    """ 
    Add two half circles to the axes *ax* (or the current axes) with the 
    specified facecolors *colors* rotated at *angle* (in degrees). 
    """ 
    if ax is None: 
     ax = plt.gca() 
    theta1, theta2 = angle, angle + 180 
    w1 = Wedge(center, radius, theta1, theta2, fc=colors[0], **kwargs) 
    w2 = Wedge(center, radius, theta2, theta1, fc=colors[1], **kwargs) 
    for wedge in [w1, w2]: 
     ax.add_artist(wedge) 
    return [w1, w2] 

main() 

enter image description here

Если вы хотите его чтобы всегда быть в начале координат, вы можете указать преобразование ax.transAxes и отключить его.

E.g.

import matplotlib.pyplot as plt 
from matplotlib.patches import Wedge 

def main(): 
    fig, ax = plt.subplots() 
    dual_half_circle(radius=0.1, angle=90, ax=ax) 
    ax.axis('equal') 
    plt.show() 

def dual_half_circle(radius, angle=0, ax=None, colors=('w','k'), **kwargs): 
    """ 
    Add two half circles to the axes *ax* (or the current axes) at the lower 
    left corner of the axes with the specified facecolors *colors* rotated at 
    *angle* (in degrees). 
    """ 
    if ax is None: 
     ax = plt.gca() 
    kwargs.update(transform=ax.transAxes, clip_on=False) 
    center = (0, 0) 
    theta1, theta2 = angle, angle + 180 
    w1 = Wedge(center, radius, theta1, theta2, fc=colors[0], **kwargs) 
    w2 = Wedge(center, radius, theta2, theta1, fc=colors[1], **kwargs) 
    for wedge in [w1, w2]: 
     ax.add_artist(wedge) 
    return [w1, w2] 

main() 

Тем не менее, это сделает «округлость» окружности зависит от соотношения сторон контура осей. (Вы можете обойти это несколькими способами, но он становится более сложным. Сообщите мне, если это то, что вы имели в виду, и я могу показать более подробный пример.) Я также, возможно, неправильно понял, что вы имели в виду «в начале» ».

+0

Да. Это в значительной степени то, что я хочу. Спасибо :) – mgilson

+0

Не проблема! Надеюсь, поможет! –

+0

add_artist не работает для меня. Мне нужно использовать add_patch. Это работает на 1.4.2, и я использовал это на гораздо более ранних версиях. –

5

Вы можете использовать полунаполненный юникод круг (U + 25D0), если у вас есть шрифт с этим символом. Как ни странно, это не в STIX (в комплекте с matplotlib), но я знаю, что это в DejaVu Sans, поэтому я буду использовать его оттуда.

enter image description here

import matplotlib.pyplot as plt 
import matplotlib.font_manager 
from numpy import * 

path = '/full/path/to/font/DejaVuSans.ttf' 
f0 = matplotlib.font_manager.FontProperties()  
f0.set_file(path) 

plt.figure() 
plt.xlim(-1.2,1.2) 
plt.ylim(-1.2,1.2) 

for angle in arange(0, 2*pi, 2*pi/10): 
    x, y = cos(angle), sin(angle) 
    plt.text(x, y, u'\u25D0', fontproperties=f0, rotation=angle*(180/pi), size=30) 

plt.show() 
+0

Это аккуратно, но вы не можете указать размер кругов в единицах оси, что я действительно хочу здесь. – mgilson