我想知道制作y标签的最佳方法是什么,标签中的每个单词都可以是不同的颜色。
我之所以会这样,是因为我将制作包含曲线(电场和矢量势场)的图。这些曲线将是不同的颜色,我想在标签中显示。以下是一个简化示例,使用上一篇文章(Matplotlib multiple colours in tick labels)来结束。这篇文章适用于x轴,但它没有正确地对y轴进行空间/顺序排列。
另一个帖子有一个类似的问题(Partial coloring of text in matplotlib),但第一个答案似乎根本不起作用,第二个答案让你将文件保存为.ps文件。
我的示例代码是
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.offsetbox import AnchoredOffsetbox, TextArea, HPacker, VPacker
ax = plt.subplot(111)
x = np.linspace(0,10,10)
y1 = x
y2 = x**2
ax.plot(x,y1,color='r',label='data1')
ax.plot(x,y2,color='b',label='data2')
ax.set_xticks([]) # empty xticklabels
ax.set_yticks([]) # empty xticklabels
# x-axis label
xbox1 = TextArea("Data1-x ", textprops=dict(color="r", size=15))
xbox2 = TextArea("and ", textprops=dict(color="k", size=15))
xbox3 = TextArea("Data2-x ", textprops=dict(color="b", size=15))
xbox = HPacker(children=[xbox1, xbox2, xbox3],
align="center", pad=0, sep=5)
anchored_xbox = AnchoredOffsetbox(loc=3, child=xbox, pad=0., frameon=False,
bbox_to_anchor=(0.3, -0.07),
bbox_transform=ax.transAxes, borderpad=0.)
# y-axis label
ybox1 = TextArea("Data1-y ", textprops=dict(color="r", size=15,rotation='vertical'))
ybox2 = TextArea("and ", textprops=dict(color="k", size=15,rotation='vertical'))
ybox3 = TextArea("Data2-y ", textprops=dict(color="b", size=15,rotation='vertical'))
ybox = VPacker(children=[ybox1, ybox2, ybox3],
align="center", pad=0, sep=5)
anchored_ybox = AnchoredOffsetbox(loc=8, child=ybox, pad=0., frameon=False,
bbox_to_anchor=(-0.08, 0.4),
bbox_transform=ax.transAxes, borderpad=0.)
ax.add_artist(anchored_xbox)
ax.add_artist(anchored_ybox)
plt.legend()
plt.show()
感谢您的帮助!
答案 0 :(得分:8)
你快到了。您只需要使用ha ='left',va ='bottom'指定文本的对齐方式。 (并翻转传递给VPacker的TextArea对象的顺序。)
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.offsetbox import AnchoredOffsetbox, TextArea, HPacker, VPacker
ax = plt.subplot(111)
x = np.linspace(0,10,10)
y1 = x
y2 = x**2
ax.plot(x,y1,color='r',label='data1')
ax.plot(x,y2,color='b',label='data2')
ybox1 = TextArea("Data2-y ", textprops=dict(color="r", size=15,rotation=90,ha='left',va='bottom'))
ybox2 = TextArea("and ", textprops=dict(color="k", size=15,rotation=90,ha='left',va='bottom'))
ybox3 = TextArea("Data1-y ", textprops=dict(color="b", size=15,rotation=90,ha='left',va='bottom'))
ybox = VPacker(children=[ybox1, ybox2, ybox3],align="bottom", pad=0, sep=5)
anchored_ybox = AnchoredOffsetbox(loc=8, child=ybox, pad=0., frameon=False, bbox_to_anchor=(-0.08, 0.4),
bbox_transform=ax.transAxes, borderpad=0.)
ax.add_artist(anchored_ybox)
plt.legend()
plt.show()
更好的是,这是一个使标签使用任意字符串和颜色列表的函数:
import numpy as np
import matplotlib.pyplot as plt
def multicolor_ylabel(ax,list_of_strings,list_of_colors,axis='x',anchorpad=0,**kw):
"""this function creates axes labels with multiple colors
ax specifies the axes object where the labels should be drawn
list_of_strings is a list of all of the text items
list_if_colors is a corresponding list of colors for the strings
axis='x', 'y', or 'both' and specifies which label(s) should be drawn"""
from matplotlib.offsetbox import AnchoredOffsetbox, TextArea, HPacker, VPacker
# x-axis label
if axis=='x' or axis=='both':
boxes = [TextArea(text, textprops=dict(color=color, ha='left',va='bottom',**kw))
for text,color in zip(list_of_strings,list_of_colors) ]
xbox = HPacker(children=boxes,align="center",pad=0, sep=5)
anchored_xbox = AnchoredOffsetbox(loc=3, child=xbox, pad=anchorpad,frameon=False,bbox_to_anchor=(0.2, -0.09),
bbox_transform=ax.transAxes, borderpad=0.)
ax.add_artist(anchored_xbox)
# y-axis label
if axis=='y' or axis=='both':
boxes = [TextArea(text, textprops=dict(color=color, ha='left',va='bottom',rotation=90,**kw))
for text,color in zip(list_of_strings[::-1],list_of_colors) ]
ybox = VPacker(children=boxes,align="center", pad=0, sep=5)
anchored_ybox = AnchoredOffsetbox(loc=3, child=ybox, pad=anchorpad, frameon=False, bbox_to_anchor=(-0.10, 0.2),
bbox_transform=ax.transAxes, borderpad=0.)
ax.add_artist(anchored_ybox)
ax = plt.subplot(111)
x = np.linspace(0,10,1000)
y1 = np.sin(x)
y2 = np.sin(2*x)
ax.plot(x,y1,color='r')
ax.plot(x,y2,color='b')
multicolor_ylabel(ax,('Line1','and','Line2','with','extra','colors!'),('r','k','b','k','m','g'),axis='both',size=15,weight='bold')
plt.show()
仍然需要摆弄“bbox_to_anchor”关键字中的位置。