python - Matplotlib:具有多种颜色的 y 轴标签

标签 python matplotlib

我想知道制作 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()

Example image

感谢您的帮助!

最佳答案

你快到了。您只需要使用 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()

enter image description here

更好的是,这是一个使用任意字符串和颜色列表制作标签的函数:

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”关键字中的位置进行一些调整。

enter image description here

关于python - Matplotlib:具有多种颜色的 y 轴标签,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33159134/

相关文章:

python - 分组所有测试 Python

python - 在 Python 中将文件和差异合并到一个新文件中

python - Scrapy 蜘蛛 : Restart spider when finishes

python - 在同一图中绘制具有不同 x 轴的线

python - 研究音调发生器程序。 'duration' 变量(以秒为单位)不能正确确定音调播放的时间

python - 使用 ElementTree/lxml 查找文本字符串的父标签

python - 导入多数组 Numpy 扩展模块失败 Visual Studio 2019 Anaconda 1.9.6 Python 3.7.1

python - 使用 matplotlib、FITTED-LINE 构建 Zipf 分布

python - Pandas 子图布局在这种情况下不起作用

python - pandas 0.21.0 时间戳与 matplotlib 的兼容性问题