为什么散点图中的点的颜色与相应图例中的点的颜色不匹配? [英] Why doesn't the color of the points in a scatter plot match the color of the points in the corresponding legend?

查看:534
本文介绍了为什么散点图中的点的颜色与相应图例中的点的颜色不匹配?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我通过以下代码通过matplotlib获得了一个示例散点图.

I have a sample scatterplot via matplotlib via the code below.

import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(0, 100, 501)
y = np.sin(x)

label = 'xy data sample'

plt.scatter(x, y, cmap='plasma', c=x, label=label)
legend_dict = dict(ncol=1, loc='best', scatterpoints=4, fancybox=True, shadow=True)
plt.legend(**legend_dict)
plt.show()

运行上面的代码将产生下面的图.

Running the code above produces the plot below.

已成功绘制了颜色图,但是图例显示的都是全蓝色的点,而不是与所选颜色图相对应的颜色的点.为什么会这样?

The colormap was successfully plotted, but the legend shows points that are all blue rather than points in a color that correspond to the chosen colormap. Why does this happen?

我尝试将cmap='plasma'放入legend_dict,但是会导致以下错误.

I tried putting cmap='plasma' in legend_dict, but it results in the error below.

File "/Users/.../
site-packages/matplotlib/axes/_axes.py", line 550, in legend
    self.legend_ = mlegend.Legend(self, handles, labels, **kwargs)
TypeError: __init__() got an unexpected keyword argument 'cmap'

我想要的输出是使图例中表示的四个点通过选定的颜色图成为不同的颜色.理想情况下,此示例中的cmap='plasma'可以使用类似于蓝点,然后是紫色点,然后是橙红色点,然后是黄色点的图例来生成图例.尽管可以使用颜色条进行选择,但我尚未浏览有关颜色条的任何文档.

My desired output is to have the four dots represented in the legend to be a different color via the chosen colormap. Ideally, cmap='plasma' in this example could produce a legend using something similar to a blue dot, then a purple dot, then an orange-red dot, then a yellow dot. Although a colorbar could make for a possible alternative, I have yet to look through any documentation about colorbars.

推荐答案

可以通过plt.colorbar()实现颜色栏.这将允许直接看到与颜色相对应的值.

A colorbar can be achieved via plt.colorbar(). This would allow to directly see the values corresponding to the colors.

使图例中的点显示不同的颜色当然也很好,尽管它不允许提供任何定量信息.

Having the points in the legend show different colors is of course also nice, although it would not allow to give any quantitative information.

不幸的是,matplotlib没有提供任何内置方法来实现此目的.因此,一种方法是将用于创建图例句柄并实现此功能的图例处理程序子类化.

Unfortunately matplotlib does not provide any inbuilt way to achieve this. So one way would be to subclass the legend handler used to create the legend handle and implement this feature.

此处,我们使用自定义的create_collection方法创建了ScatterHandler,在该方法中,我们创建了所需的PathCollection,并在图例的legend_map词典中指定了它来使用它.

Here we create a ScatterHandler with a custom create_collection method, in which we create the desired PathCollection and use this by specifying it in the legend_map dictionary of the legend.

handler_map={ type(sc) : ScatterHandler()}

以下代码乍看之下似乎有些复杂,但是您可以在不完全理解该类的情况下直接复制该类,并在您的代码中使用它.

The following code seems a bit complicated at first sight, however you may simply copy the class without understanding it completely and use it in your code.

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.legend_handler import HandlerRegularPolyCollection

class ScatterHandler(HandlerRegularPolyCollection):
    def update_prop(self, legend_handle, orig_handle, legend):
        legend._set_artist_props(legend_handle)
        legend_handle.set_clip_box(None)
        legend_handle.set_clip_path(None)

    def create_collection(self, orig_handle, sizes, offsets, transOffset):
        p = type(orig_handle)([orig_handle.get_paths()[0]],
                              sizes=sizes, offsets=offsets,
                              transOffset=transOffset,
                              cmap=orig_handle.get_cmap(),
                              norm=orig_handle.norm )

        a = orig_handle.get_array()
        if type(a) != type(None):
            p.set_array(np.linspace(a.min(),a.max(),len(offsets)))
        else:
            self._update_prop(p, orig_handle)
        return p


x = np.linspace(0, 100, 501)
y = np.sin(x)*np.cos(x/50.)

sc = plt.scatter(x, y, cmap='plasma', c=x, label='xy data sample')

legend_dict = dict(ncol=1, loc='best', scatterpoints=4, fancybox=True, shadow=True)
plt.legend(handler_map={type(sc) : ScatterHandler()}, **legend_dict)

plt.show()

这篇关于为什么散点图中的点的颜色与相应图例中的点的颜色不匹配?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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