Matplotlib:具有多种颜色的 y 轴标签 [英] Matplotlib: y-axis label with multiple colors

查看:58
本文介绍了Matplotlib:具有多种颜色的 y 轴标签的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道制作 y 标签的最佳方法是什么,标签中的每个单词都可以是不同的颜色.

我想要这个的原因是因为我将制作包含曲线(电场和矢量势场)的图.这些曲线将使用不同的颜色,我希望在标签中显示出来.以下是一个简化的示例,使用了以前的文章(

感谢您的帮助!

解决方案

您就快到了.您只需要使用 ha='left',va='bottom' 指定文本的对齐方式.(并翻转传递给VPacker的TextArea对象的顺序).

将 numpy 导入为 np导入matplotlib.pyplot作为plt从 matplotlib.offsetbox 导入 AnchoredOffsetbox、TextArea、HPacker、VPackerax = plt.subplot(111)x = np.linspace(0,10,10)y1 = xy2 = x**2ax.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()

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

将 numpy 导入为 np导入matplotlib.pyplot作为pltdef multicolor_ylabel(ax,list_of_strings,list_of_colors,axis='x',anchorpad=0,**kw):"""此函数创建具有多种颜色的轴标签ax 指定应在其中绘制标签的轴对象list_of_strings是所有文本项的列表list_if_colors是字符串的相应颜色列表axis='x'、'y' 或 'both' 并指定应绘制哪个标签"""从 matplotlib.offsetbox 导入 AnchoredOffsetbox、TextArea、HPacker、VPacker#x轴标签如果axis =='x'或axis =='both':boxs = [TextArea(text,textprops = dict(color = color,ha ='left',va ='bottom',** kw))用于文本,邮政编码中的颜色(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 =='y'或axis =='both':box = [TextArea(text, textprops=dict(color=color, ha='left',va='bottom',rotation=90,**kw))对于文本,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"中的位置.

I was wondering what the best way to make a y-label where each word in the label can be a different color.

The reason I would like this is because I will be making plots that will contain to curves (Electric Fields and Vector Potential Fields). These curves will be different colors and I would like to show this in the labels. The following is a simplified example, using a previous post (Matplotlib multiple colours in tick labels) to get close. This post does well for the x-axis, however it doesn't space/order the y-axis correctly.

Another post had a similar question (Partial coloring of text in matplotlib), but the first answer didn't seem to work at all anymore and the second answer makes you save the file as a .ps file.

My example code is

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

Thanks for the help!

解决方案

You were almost there. You just need to specify the alignment of the text using ha='left',va='bottom'. (And flip the order of the TextArea objects passed to VPacker).

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

Better yet, here is a function that makes the labels using an arbitrary list of strings and colors:

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

It still takes some fiddling with the positions in the "bbox_to_anchor" keyword.

这篇关于Matplotlib:具有多种颜色的 y 轴标签的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆