Python 如何在 matplotlib 中向 im​​show() 添加图例

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25482876/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 20:17:03  来源:igfitidea点击:

How to add legend to imshow() in matplotlib

pythonmatplotliblabellegendimshow

提问by rankthefirst

I am using matplotlib

我在用 matplotlib

In plot()or bar(), we can easily put legend, if we add labels to them. but what if it is a contourf()or imshow()

plot()or 中bar(),如果我们为它们添加标签,我们可以轻松地放置图例。但如果它是一个contourf()imshow()

I know there is a colorbar()which can present the color range, but it is not satisfied. I want such a legend which have names(labels).

我知道有一个colorbar()可以呈现颜色范围的,但它并不满足。我想要这样一个有名字(标签)的图例。

enter image description here

在此处输入图片说明

For what I can think of is that, add labels to each element in the matrix, then ,try legend(), to see if it works, but how to add label to the element, like a value??

我能想到的是,为矩阵中的每个元素添加标签,然后尝试legend(),看看它是否有效,但是如何为元素添加标签,比如一个值??

in my case, the raw data is like:

就我而言,原始数据如下:

1,2,3,3,4
2,3,4,4,5
1,1,1,2,2

for example, 1 represents 'grass', 2 represents 'sand', 3 represents 'hill'... and so on. imshow() works perfectly with my case, but without the legend.

例如,1 代表“草”,2 代表“沙”,3 代表“山”……等等。imshow() 与我的案例完美搭配,但没有图例。

my question is:

我的问题是:

  1. Is there a function that can automatically add legend, for example, in my case, I just have to do like this: someFunction('grass','sand',...)

  2. If there isn't, how do I add labels to each value in the matrix. For example, label all the 1 in the matrix 'grass', labell all the 2 in the matrix 'sand'...and so on.

  1. 有没有可以自动添加图例的函数,例如,就我而言,我只需要这样做: someFunction('grass','sand',...)

  2. 如果没有,我如何为矩阵中的每个值添加标签。例如,标记矩阵“grass”中的所有 1,标记矩阵“sand”中的所有 2……等等。

Thank you!

谢谢!

Edit:

编辑

Thanks to @dnalow, it's smart really. However, I still wonder if there is any formal solution.

感谢@dnalow,它真的很聪明。但是,我仍然想知道是否有任何正式的解决方案。

采纳答案by dnalow

I guess you have to fake your legend, since it requires a line for creating the legend.

我想你必须伪造你的图例,因为它需要一条线来创建图例。

You can do something like this:

你可以这样做:

import pylab as pl
mycmap = pl.cm.jet # for example
for entry in pl.unique(raw_data):
    mycolor = mycmap(entry*255/(max(raw_data) - min(raw_data)))
    pl.plot(0, 0, "-", c=mycolor, label=mynames[entry])

pl.imshow(raw_data)
pl.legend()

Of cause this is not very satisfying yet. But maybe you can build something on that.

当然,这还不是很令人满意。但也许你可以在此基础上构建一些东西。

[edit: added missing parenthesis]

[编辑:添加了缺少的括号]

回答by mark jay

You could use matplotlib.pylab.textto add text to your plot and customize it to look like a legend

您可以使用matplotlib.pylab.text向情节添加文本并将其自定义为图例

For example:

例如:

import numpy as np
import matplotlib.cm as cm
import matplotlib.pylab as plt

raw_data = np.random.random((100, 100))
fig, ax = plt.subplots(1)
ax.imshow(raw_data, interpolation='nearest', cmap=cm.gray)
ax.text(5, 5, 'your legend', bbox={'facecolor': 'white', 'pad': 10})
plt.show()

which gives you following random noise

这让你跟随 随机噪声

You can check out the matplotlib documentation on text for more details matplotlib text examples

您可以查看关于文本的 matplotlib 文档以获取更多详细信息matplotlib 文本示例

回答by ImportanceOfBeingErnest

I quote here a solution to a similar question, in case someone is still interested:

我在这里引用了一个类似问题的解决方案,以防有人仍然感兴趣:

I suppose putting a legend for all values in a matrix only makes sense if there aren't too many of them. So let's assume you have 8 different values in your matrix. We can then create a proxy artist of the respective color for each of them and put them into a legend like this

我想在矩阵中为所有值放置一个图例只有在它们不是太多时才有意义。因此,让我们假设您的矩阵中有 8 个不同的值。然后我们可以为他们每个人创建一个各自颜色的代理艺术家,并将他们放入这样的图例中

import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
import numpy as np

# create some data
data = np.random.randint(0, 8, (5,5))
# get the unique values from data
# i.e. a sorted list of all values in data
values = np.unique(data.ravel())

plt.figure(figsize=(8,4))
im = plt.imshow(data, interpolation='none')

# get the colors of the values, according to the 
# colormap used by imshow
colors = [ im.cmap(im.norm(value)) for value in values]
# create a patch (proxy artist) for every color 
patches = [ mpatches.Patch(color=colors[i], label="Level {l}".format(l=values[i]) ) for i in range(len(values)) ]
# put those patched as legend-handles into the legend
plt.legend(handles=patches, bbox_to_anchor=(1.05, 1), loc=2, borderaxespad=0. )

plt.grid(True)
plt.show()

enter image description here

在此处输入图片说明

回答by Jingtao Yao

I am just working on the same project to draw a land use map like your problem. Here is my solution following the answers above.

我只是在同一个项目上工作,以绘制像您的问题一样的土地利用地图。这是我按照上述答案的解决方案。

import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
import numpy as np
##arrayLucc is the array of land use types 
arrayLucc = np.random.randint(1,4,(5,5))
## first you need to define your color map and value name as a dic
t = 1 ## alpha value
cmap = {1:[0.1,0.1,1.0,t],2:[1.0,0.1,0.1,t],3:[1.0,0.5,0.1,t]}
labels = {1:'agricultural land',2:'forest land',3:'grassland'}
arrayShow = np.array([[cmap[i] for i in j] for j in arrayLucc])    
## create patches as legend
patches =[mpatches.Patch(color=cmap[i],label=labels[i]) for i in cmap]

plt.imshow(arrayShow)
plt.legend(handles=patches, loc=4, borderaxespad=0.)
plt.show()

result show below

结果显示如下

This resolution doesn't seem very good but it can works. I am also looking for my other methods.

这个分辨率看起来不是很好,但它可以工作。我也在寻找我的其他方法。