温馨提示:本文翻译自stackoverflow.com,查看原文请点击:python - Matplotlib legend makes the image too large
legend matplotlib plot python

python - Matplotlib图例使图像太大

发布于 2020-05-03 06:57:44

我正在用matplotlib绘制该图,for循环只是为背景着色:

fig, ax = plt.subplots()

ax.set_ylabel('Number of contacts')  
ax.set_xlabel('Time [s]') 

for m in range(len(data[node])):
    if data[node][m] == -1:
        ax.axvline(m,color='r',linewidth=5,alpha=0.2,label="OUT")
    if data[node][m] == 0:
        ax.axvline(m,color='g',linewidth=5,alpha=0.2,label="RZ0")
    if data[node][m] == 1:
        ax.axvline(m,color='y',linewidth=5,alpha=0.2,label="RZ1")

ax.plot(x, y, 'b+')
# ax.legend() # HERE is the problem
plt.show()

绘制以下内容:

在此处输入图片说明

我现在想要的是一个图例,以指示背景含义的每种颜色,但是当包含在内时ax.legend(),出现以下错误:

ValueError: Image size of 392x648007 pixels is too large. It must be less than 2^16 in each 
direction.

<Figure size 432x288 with 1 Axes>
<Figure size 432x288 with 0 Axes>

我应该如何命名背景的每种颜色,有43200条垂直线,但只有3种颜色,它与行数有关吗?

查看更多

提问者
BlueMountain
被浏览
34
JohanC 2020-02-14 20:16

诀窍是仅将标签设置一次。您可以为每个标签添加一个变量,并在使用None后将其替换为变量注意,使用axvline背景绘制存在以下问题:线宽是在像素空间中测量的,因此相邻的线会重叠或之间有小的空白。更好地使用axvspan为了避免左右两边的空白,您可以显式设置x限制。

使用循环可以稍微简化代码。

更新的代码:

  • 将连续的跨度分组以进行绘制
  • 预先计算Alpha的效果,因此无需透明度即可绘制背景
from matplotlib import pyplot as plt
from matplotlib import colors as mcolors
import numpy as np
import pandas as pd
import itertools

fig, ax = plt.subplots()

# create some random data
x = np.arange(100)
y = np.sinh(x/20)
indicators = [-1, 0, 1]
node = 0
data = [np.random.choice(indicators, len(x), p=[10/16,1/16,5/16])]

labels = ["OUT", "RZ0", "RZ1"]
colors = ['lime', 'purple', 'gold']

alpha = 0.4
# precalculate the effect of alpha so the colors can be applied with alpha=1
colors = [[1 + (x - 1) * alpha for x in mcolors.to_rgb(c)] for c in colors]

m = 0
for val, group in itertools.groupby(data[node]):
    width = len(list(group))
    ind = indicators.index(val)
    ax.axvspan(m, m + width, color=colors[ind], linewidth=0, alpha=1, label=labels[ind])
    labels[ind] = None  # reset the label to make sure it is only used once
    m += width

ax.plot(x, y, 'b+')
ax.set_xlim(0, len(data[node]))
ax.legend(framealpha=1) # to make the legend background opaque
plt.show()

样地