How can I make the xtick labels of a plot be simple drawings using matplotlib?
我想用一个简单的图形(由线和圆组成)作为每个x刻度的标签,而不是用单词或数字作为x轴的刻度标签。 这可能吗? 如果是这样,在matplotlib中进行处理的最佳方法是什么?
我将删除刻度线标签,并用补丁替换文本。这是执行此任务的简短示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | import matplotlib.pyplot as plt import matplotlib.patches as patches # define where to put symbols vertically TICKYPOS = -.6 fig = plt.figure() ax = fig.add_subplot(111) ax.plot(range(10)) # set ticks where your images will be ax.get_xaxis().set_ticks([2,4,6,8]) # remove tick labels ax.get_xaxis().set_ticklabels([]) # add a series of patches to serve as tick labels ax.add_patch(patches.Circle((2,TICKYPOS),radius=.2, fill=True,clip_on=False)) ax.add_patch(patches.Circle((4,TICKYPOS),radius=.2, fill=False,clip_on=False)) ax.add_patch(patches.Rectangle((6-.1,TICKYPOS-.05),.2,.2, fill=True,clip_on=False)) ax.add_patch(patches.Rectangle((8-.1,TICKYPOS-.05),.2,.2, fill=False,clip_on=False)) |
结果如下图:
将
如果您有要用于符号的特定图像文件,则可以使用
1 2 3 4 5 6 7 8 9 10 | import matplotlib.pyplot as plt fig = plt.figure(figsize=(1,1),dpi=400) ax = fig.add_axes([0,0,1,1],frameon=False) ax.set_axis_off() ax.plot(range(10),linewidth=32) ax.plot(range(9,-1,-1),linewidth=32) fig.savefig('thumb.png') |
产生此图像:
然后,我在想要刻度线标签的位置创建了一个BboxImage,并设置了所需的大小:
1 2 3 4 5 6 7 8 9 10 11 12 | lowerCorner = ax.transData.transform((.8,TICKYPOS-.2)) upperCorner = ax.transData.transform((1.2,TICKYPOS+.2)) bbox_image = BboxImage(Bbox([lowerCorner[0], lowerCorner[1], upperCorner[0], upperCorner[1], ]), norm = None, origin=None, clip_on=False, ) |
注意我如何使用
现在,我使用
1 2 | bbox_image.set_data(imread('thumb.png')) ax.add_artist(bbox_image) |
结果是一个更新的数字:
如果您确实直接使用图像,请确保导入所需的类和方法:
1 2 | from matplotlib.image import BboxImage,imread from matplotlib.transforms import Bbox |
另一个答案有一些缺点,因为它使用静态坐标。因此,在更改图形大小或缩放和平移绘图时,它将不起作用。
更好的选择是直接在所选坐标系中定义位置。对于x轴,将数据坐标用于x位置,将轴坐标用于y位置是有意义的。
使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | import matplotlib.pyplot as plt import matplotlib.patches as mpatches from matplotlib.offsetbox import (DrawingArea, OffsetImage,AnnotationBbox) fig, ax = plt.subplots() ax.plot([-10,10], [1,3]) # Annotate the 1st position with a circle patch da = DrawingArea(20, 20, 10, 10) p = mpatches.Circle((0, 0), 10) da.add_artist(p) ab = AnnotationBbox(da, (-5,0), xybox=(0, -7), xycoords=("data","axes fraction"), box_alignment=(.5, 1), boxcoords="offset points", bboxprops={"edgecolor" :"none"}) ax.add_artist(ab) # Annotate the 2nd position with an image arr_img = plt.imread("https://i.stack.imgur.com/FmX9n.png", format='png') imagebox = OffsetImage(arr_img, zoom=0.2) imagebox.image.axes = ax ab = AnnotationBbox(imagebox, (5,0), xybox=(0, -7), xycoords=("data","axes fraction"), boxcoords="offset points", box_alignment=(.5, 1), bboxprops={"edgecolor" :"none"}) ax.add_artist(ab) plt.show() |
请注意,许多形状以unicode符号的形式存在,因此人们可以简单地用这些符号设置刻度标签。有关这种解决方案,请参见如何在matplotlib或seaborn中使用彩色形状作为yticks?