Matplotlib 半黑半白圆圈

15 投票
2 回答
9460 浏览
提问于 2025-04-17 18:36

我想在matplotlib的图表中放一个半黑半白的圆圈,半径为R,位置在原点。我知道有一个叫做Circle类的东西,但我不知道怎么设置让圆的左半边是白色,右半边是黑色。(理想的解决方案是让我可以指定圆的方向,比如我应该能旋转它,让上半部分是白色,下半部分是黑色)。

2 个回答

7

如果你的字体里有这个符号,你可以使用unicode半填充圆圈(U+25D0)。奇怪的是,这个符号在STIX字体里没有(STIX是matplotlib自带的字体),但我知道DejaVu Sans字体里有,所以我会从那里使用它。

在这里输入图片描述

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()
21

最简单的方法是使用两个 Wedge。 (这样做不会自动调整坐标轴的比例,不过如果你想的话,这个也很简单可以加上。)

这里有个快速的例子:

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()

在这里输入图片描述

如果你希望它总是位于原点,可以指定变换为 ax.transAxes,并关闭剪切功能。

例如:

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()

不过,这样会导致圆的“圆形度”依赖于坐标轴外框的长宽比。(你可以通过几种方法来解决这个问题,但会变得更复杂。如果你想了解这个,我可以给你展示一个更详细的例子。)我可能也误解了你所说的“在原点”的意思。

撰写回答