Python 来自 Pandas 数据帧的具有不同大小、标记和颜色的散点图

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/30313882/
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-19 08:13:25  来源:igfitidea点击:

Scatterplot with different size, marker, and color from pandas dataframe

pythonmatplotlibscatter-plotmarkercolorbar

提问by Kexin Xu

I am trying to do a scatter plot with speed over meters for each point where marker indicate different types, size indicate different weights and color indicate how old a point is over 10 minutes scale. However, I was only able to plot by size so far.

我正在尝试为每个点绘制速度超过米的散点图,其中标记表示不同的类型,大小表示不同的权重,颜色表示一个点超过 10 分钟的规模。但是,到目前为止,我只能按大小进行绘图。

Any help is highly appreciated.

任何帮助都受到高度赞赏。

x = {'speed': [10, 15, 20, 18, 19], 'meters' : [122, 150, 190, 230, 300], 'type': ['phone', 'phone', 'gps', 'gps', 'car'], 'weight': [0.2, 0.3, 0.1, 0.85, 0.0], 'old': [1, 2, 4, 5, 8]}

m = pd.DataFrame(x)

plt.scatter(m.meters, m.speed, s = 30* m.weight)

mkr_dict = {'gps': 'x', 'phone': '+', 'car': 'o'}

   meters  speed   type  weight  old
0     122     10  phone    0.20    1
1     150     15  phone    0.30    2
2     190     20    gps    0.10    4
3     230     18    gps    0.85    5
4     300     19    car    0.00    8

Updated question:

更新的问题:

I am trying to add colorbar to the color scale based on old. it worked when I plot against the entire dataset but failed after trying to add marker for each subset. Any idea?

我正在尝试将颜色条添加到基于旧的色标中。当我针对整个数据集进行绘图时它起作用,但在尝试为每个子集添加标记后失败。任何的想法?

plt.scatter(m.meters, m.speed, s = 30* m.weight, c=m.old)
cbar = plt.colorbar(ticks = [0, 5, 10])
cbar.ax.set_yticklabels(['New','5mins', '10mins'])

TypeError: You must first set_array for mappable

类型错误:您必须先为可映射设置 set_array

采纳答案by cphlewis

scattercan only do one kind of marker at a time, so you have to plot the different types separately. Fortunately pandas makes this easy:

scatter一次只能做一种标记,所以你必须分别绘制不同的类型。幸运的是,pandas 让这一切变得简单:

import matplotlib.pyplot as plt
import pandas as pd
x = {'speed': [10, 15, 20, 18, 19],
     'meters' : [122, 150, 190, 230, 300],
     'type': ['phone', 'phone', 'gps', 'gps', 'car'],
     'weight': [0.2, 0.3, 0.1, 0.85, 0.0],
     'old': [1, 2, 4, 5, 8]}

m = pd.DataFrame(x)
mkr_dict = {'gps': 'x', 'phone': '+', 'car': 'o'}
for kind in mkr_dict:
    d = m[m.type==kind]
    plt.scatter(d.meters, d.speed, 
                s = 100* d.weight, 
                c = d.old, 
                marker = mkr_dict[kind])
plt.show()

enter image description here

在此处输入图片说明

.... Where's the car? Well, the weight is 0.0 in the original test data, and we're using weight for marker-size, so: can't see it.

……车呢?嗯,原始测试数据中的权重是 0.0,我们使用权重作为标记大小,所以:看不到它。

回答by xnx

If you have just a few points, as here, you can pass a list of floats to the cargument:

如果您只有几点,如这里,您可以将浮点数列表传递给c参数:

colors = ['r', 'b', 'k', 'g', 'm']
plt.scatter(m.meters, m.speed, s=30*m.weight, vmin=0, vmax=10, cmap=cm)

to have your points coloured in the order given. Alternatively, to use a colormap:

按照给定的顺序对您的点进行着色。或者,要使用颜色图:

cm = plt.cm.get_cmap('hot')  # or your colormap of choice
plt.scatter(m.meters, m.speed, s=30*m.weight, c=m.old, cmap=cm)

To change the marker shapes, you either need to add your own Patches, or add one point at a time: e.g.

要更改标记形状,您需要添加自己的Patches,或者一次添加一个点:例如

markers = ['^', 'o', 'v', 's', 'd']
for px, py, c, s, t in zip(m.meters, m.speed, m.old, m.weight, markers):
    plt.scatter(px, py, marker=t, c=cm(c/10.), vmin=0, vmax=10, s=400*s+100)
plt.show()

enter image description here

在此处输入图片说明

(I've scaled the m.weightto a different range to see the 5th point, which would otherwise have size 0.0).

(我已将 缩放m.weight到不同的范围以查看第 5 个点,否则该点的大小为 0.0)。