如何忽略子图图例中的某些标签?
How to ignore some labels in subplots legend?
我有一个图,其中包含我使用熊猫数据框的数据创建的子图:
# Definition of the dataframe
df = pd.DataFrame({'Colors': {0: 'Red', 1: 'Blue', 2: 'Green', 3: 'Blue', 4: 'Red'}, 'X_values': {0: 1, 1: 2, 2: 3, 3: 4, 4: 5}, 'Y_values': {0: 2, 1: 4, 2: 8, 3: 10, 4: 4}, 'MinY_values': {0: 1.5, 1: 3, 2: 7.5, 3: 8, 4: 2}, 'MaxY_values': {0: 2.5, 1: 5, 2: 9.5, 3: 11, 4: 6}})
我定义了两个列表,其中包含图中每个点的颜色以及我想分配给每个点的标签(然后,如果需要,我可以更改给定点的标签):
color
Out[8]: ['red', 'blue', 'green', 'blue', 'red']
labels
Out[9]:
['It is a red point',
'What a wonderful blue point',
'Sounds to be a green point',
'What a wonderful blue point',
'It is a red point']
在每个子图中,我需要添加一条水平线。
这是我的问题:当我向图形添加图例时,如果颜色重复,则标签会重复,并且图例中包含水平线,这将“移动”图例。
如何忽略图例中重复的颜色以及不包括其中的黑线?
这是我的代码:
import pandas as pd
from matplotlib.pyplot import show, subplots
# Definition of the dataframe
df = pd.DataFrame({'Colors': {0: 'Red', 1: 'Blue', 2: 'Green', 3: 'Blue', 4: 'Red'}, 'X_values': {0: 1, 1: 2, 2: 3, 3: 4, 4: 5}, 'Y_values': {0: 2, 1: 4, 2: 8, 3: 10, 4: 4}, 'MinY_values': {0: 1.5, 1: 3, 2: 7.5, 3: 8, 4: 2}, 'MaxY_values': {0: 2.5, 1: 5, 2: 9.5, 3: 11, 4: 6}})
# Definition of the different colors and labels
color = []
labels = []
for i in df['Colors']:
if i == 'Red':
color.append('red')
labels.append('It is a red point')
if i == 'Blue':
color.append('blue')
labels.append('What a wonderful blue point')
if i == 'Green':
color.append('green')
labels.append('Sounds to be a green point')
# Figure
fig,axes = subplots(3,1,sharex = True)
fig.subplots_adjust(top=0.975,
bottom=0.07,
left=0.05,
right=0.585,
hspace=0.0,
wspace=0.2)
for x_val,y_val,min_val,max_val,colors in zip(df['X_values'],df['Y_values'],df['MinY_values'],df['MaxY_values'],color):
axes[0].errorbar(x_val,y_val,yerr = [[min_val],[max_val]] ,color = colors,barsabove='True',fmt = 'o')
axes[0].axhline(y=5, color='black', linestyle='--')
for x_val,y_val,min_val,max_val,colors in zip(df['X_values'],df['Y_values'],df['MinY_values'],df['MaxY_values'],color):
axes[1].errorbar(x_val,y_val,yerr = [[min_val],[max_val]] ,color = colors,barsabove='True',fmt = 'o')
axes[1].axhline(y=5, color='black', linestyle='--')
for x_val,y_val,min_val,max_val,colors in zip(df['X_values'],df['Y_values'],df['MinY_values'],df['MaxY_values'],color):
axes[2].errorbar(x_val,y_val,yerr = [[min_val],[max_val]] ,color = colors,barsabove='True',fmt = 'o',label = labels)
axes[2].axhline(y=5, color='black', linestyle='--')
# Legend
fig.legend(labels)
fig.legend(bbox_to_anchor=(2,2), loc='center', ncol=1)
show()
在这种情况下,最简单的方法是创建自定义图例。
一些注意事项:
plt.tight_layout()
可用于将图例和标签很好地放入图中;这比 fig.subplots_adjust()
灵活得多,尤其是在以后对绘图进行更改时
fig.legend()
使用“当前斧头”(当前子图),在本例中为 axes[2]
- 将图例放在图的右侧时,使用
loc='upper left'
作为锚点会有所帮助; 'loc' 不在左侧的值太难控制(bbox_to_anchor
设置锚点的位置,在给定子图的 'axes coordinates' 中测量)
这是一个例子:
from matplotlib import pyplot as plt
from matplotlib.lines import Line2D
import pandas as pd
# Definition of the dataframe
df = pd.DataFrame(
{'Colors': {0: 'Red', 1: 'Blue', 2: 'Green', 3: 'Blue', 4: 'Red'}, 'X_values': {0: 1, 1: 2, 2: 3, 3: 4, 4: 5},
'Y_values': {0: 2, 1: 4, 2: 8, 3: 10, 4: 4}, 'MinY_values': {0: 1.5, 1: 3, 2: 7.5, 3: 8, 4: 2},
'MaxY_values': {0: 2.5, 1: 5, 2: 9.5, 3: 11, 4: 6}})
fig, axes = plt.subplots(3, 1, sharex=True, gridspec_kw={'hspace': 0.0})
for x_val, y_val, min_val, max_val, color in zip(df['X_values'], df['Y_values'],
df['MinY_values'], df['MaxY_values'], df['Colors']):
axes[0].errorbar(x_val, y_val, yerr=[[min_val], [max_val]], color=color, barsabove='True', fmt='o')
axes[0].axhline(y=5, color='black', linestyle='--')
for x_val, y_val, min_val, max_val, color in zip(df['X_values'], df['Y_values'],
df['MinY_values'], df['MaxY_values'], df['Colors']):
axes[1].errorbar(x_val, y_val, yerr=[[min_val], [max_val]], color=color, barsabove='True', fmt='o')
axes[1].axhline(y=5, color='black', linestyle='--')
for x_val, y_val, min_val, max_val, color in zip(df['X_values'], df['Y_values'],
df['MinY_values'], df['MaxY_values'], df['Colors']):
axes[2].errorbar(x_val, y_val, yerr=[[min_val], [max_val]], color=color, barsabove='True', fmt='o')
axes[2].axhline(y=5, color='black', linestyle='--')
# Legend
legend_handles = [Line2D([], [], color='red', label='It is a red point', marker='o', ls='-'),
Line2D([], [], color='blue', label='What a wonderful blue point', marker='o', ls='-'),
Line2D([], [], color='green', label='Sounds to be a green point', marker='o', ls='-')]
axes[0].legend(handles=legend_handles, bbox_to_anchor=(1.01, 1), loc='upper left', ncol=1)
plt.tight_layout()
plt.show()
我有一个图,其中包含我使用熊猫数据框的数据创建的子图:
# Definition of the dataframe
df = pd.DataFrame({'Colors': {0: 'Red', 1: 'Blue', 2: 'Green', 3: 'Blue', 4: 'Red'}, 'X_values': {0: 1, 1: 2, 2: 3, 3: 4, 4: 5}, 'Y_values': {0: 2, 1: 4, 2: 8, 3: 10, 4: 4}, 'MinY_values': {0: 1.5, 1: 3, 2: 7.5, 3: 8, 4: 2}, 'MaxY_values': {0: 2.5, 1: 5, 2: 9.5, 3: 11, 4: 6}})
我定义了两个列表,其中包含图中每个点的颜色以及我想分配给每个点的标签(然后,如果需要,我可以更改给定点的标签):
color
Out[8]: ['red', 'blue', 'green', 'blue', 'red']
labels
Out[9]:
['It is a red point',
'What a wonderful blue point',
'Sounds to be a green point',
'What a wonderful blue point',
'It is a red point']
在每个子图中,我需要添加一条水平线。
这是我的问题:当我向图形添加图例时,如果颜色重复,则标签会重复,并且图例中包含水平线,这将“移动”图例。
如何忽略图例中重复的颜色以及不包括其中的黑线?
这是我的代码:
import pandas as pd
from matplotlib.pyplot import show, subplots
# Definition of the dataframe
df = pd.DataFrame({'Colors': {0: 'Red', 1: 'Blue', 2: 'Green', 3: 'Blue', 4: 'Red'}, 'X_values': {0: 1, 1: 2, 2: 3, 3: 4, 4: 5}, 'Y_values': {0: 2, 1: 4, 2: 8, 3: 10, 4: 4}, 'MinY_values': {0: 1.5, 1: 3, 2: 7.5, 3: 8, 4: 2}, 'MaxY_values': {0: 2.5, 1: 5, 2: 9.5, 3: 11, 4: 6}})
# Definition of the different colors and labels
color = []
labels = []
for i in df['Colors']:
if i == 'Red':
color.append('red')
labels.append('It is a red point')
if i == 'Blue':
color.append('blue')
labels.append('What a wonderful blue point')
if i == 'Green':
color.append('green')
labels.append('Sounds to be a green point')
# Figure
fig,axes = subplots(3,1,sharex = True)
fig.subplots_adjust(top=0.975,
bottom=0.07,
left=0.05,
right=0.585,
hspace=0.0,
wspace=0.2)
for x_val,y_val,min_val,max_val,colors in zip(df['X_values'],df['Y_values'],df['MinY_values'],df['MaxY_values'],color):
axes[0].errorbar(x_val,y_val,yerr = [[min_val],[max_val]] ,color = colors,barsabove='True',fmt = 'o')
axes[0].axhline(y=5, color='black', linestyle='--')
for x_val,y_val,min_val,max_val,colors in zip(df['X_values'],df['Y_values'],df['MinY_values'],df['MaxY_values'],color):
axes[1].errorbar(x_val,y_val,yerr = [[min_val],[max_val]] ,color = colors,barsabove='True',fmt = 'o')
axes[1].axhline(y=5, color='black', linestyle='--')
for x_val,y_val,min_val,max_val,colors in zip(df['X_values'],df['Y_values'],df['MinY_values'],df['MaxY_values'],color):
axes[2].errorbar(x_val,y_val,yerr = [[min_val],[max_val]] ,color = colors,barsabove='True',fmt = 'o',label = labels)
axes[2].axhline(y=5, color='black', linestyle='--')
# Legend
fig.legend(labels)
fig.legend(bbox_to_anchor=(2,2), loc='center', ncol=1)
show()
在这种情况下,最简单的方法是创建自定义图例。
一些注意事项:
plt.tight_layout()
可用于将图例和标签很好地放入图中;这比fig.subplots_adjust()
灵活得多,尤其是在以后对绘图进行更改时fig.legend()
使用“当前斧头”(当前子图),在本例中为axes[2]
- 将图例放在图的右侧时,使用
loc='upper left'
作为锚点会有所帮助; 'loc' 不在左侧的值太难控制(bbox_to_anchor
设置锚点的位置,在给定子图的 'axes coordinates' 中测量)
这是一个例子:
from matplotlib import pyplot as plt
from matplotlib.lines import Line2D
import pandas as pd
# Definition of the dataframe
df = pd.DataFrame(
{'Colors': {0: 'Red', 1: 'Blue', 2: 'Green', 3: 'Blue', 4: 'Red'}, 'X_values': {0: 1, 1: 2, 2: 3, 3: 4, 4: 5},
'Y_values': {0: 2, 1: 4, 2: 8, 3: 10, 4: 4}, 'MinY_values': {0: 1.5, 1: 3, 2: 7.5, 3: 8, 4: 2},
'MaxY_values': {0: 2.5, 1: 5, 2: 9.5, 3: 11, 4: 6}})
fig, axes = plt.subplots(3, 1, sharex=True, gridspec_kw={'hspace': 0.0})
for x_val, y_val, min_val, max_val, color in zip(df['X_values'], df['Y_values'],
df['MinY_values'], df['MaxY_values'], df['Colors']):
axes[0].errorbar(x_val, y_val, yerr=[[min_val], [max_val]], color=color, barsabove='True', fmt='o')
axes[0].axhline(y=5, color='black', linestyle='--')
for x_val, y_val, min_val, max_val, color in zip(df['X_values'], df['Y_values'],
df['MinY_values'], df['MaxY_values'], df['Colors']):
axes[1].errorbar(x_val, y_val, yerr=[[min_val], [max_val]], color=color, barsabove='True', fmt='o')
axes[1].axhline(y=5, color='black', linestyle='--')
for x_val, y_val, min_val, max_val, color in zip(df['X_values'], df['Y_values'],
df['MinY_values'], df['MaxY_values'], df['Colors']):
axes[2].errorbar(x_val, y_val, yerr=[[min_val], [max_val]], color=color, barsabove='True', fmt='o')
axes[2].axhline(y=5, color='black', linestyle='--')
# Legend
legend_handles = [Line2D([], [], color='red', label='It is a red point', marker='o', ls='-'),
Line2D([], [], color='blue', label='What a wonderful blue point', marker='o', ls='-'),
Line2D([], [], color='green', label='Sounds to be a green point', marker='o', ls='-')]
axes[0].legend(handles=legend_handles, bbox_to_anchor=(1.01, 1), loc='upper left', ncol=1)
plt.tight_layout()
plt.show()