Matplotlib:将一组散点图数据放在最前面

时间:2018-11-08 18:25:23

标签: python matplotlib scatter

我有一系列带有红色和蓝色标记的子图,我对红色标记最感兴趣,因此想将它们带到绘图的前面:

enter image description here

数据结构如下:

            SzT     Pcp     Pcp_3day    Pcp_7day    Pcp_10day   Pcp_14day   Pcp_21day   Pcp_28day
date        
2017-12-04  0.0     8.382   19.304      21.082      40.132      40.132      42.418      71.374
2017-12-05  0.0     12.192  20.574      33.020      42.164      52.324      52.578      81.534
2017-12-06  0.0     1.016   21.590      33.020      34.290      53.340      53.594      82.550
2017-12-07  0.0     12.700  25.908      45.466      46.990      66.040      66.040      95.250
2017-12-08  0.0     5.080   18.796      50.292      51.816      71.120      71.120      88.900

颜色由每个数据点所属的“ SzT”值确定,该值可以是1或0(尽管在上面仅显示了“ 0”)。我用下面的代码构造了它:

colors = {0 : 'b',
          1 : 'r'}


fig = plt.figure(figsize=(20,10))
ax = fig.add_subplot(111)
ax1 = fig.add_subplot(221)
ax2 = fig.add_subplot(222)
ax3 = fig.add_subplot(223)
ax4 = fig.add_subplot(224)

c = [colors[i] for i in RGDFT8mm['SzT']]
m = [marker[i] for i in RGDFT8mm['SzT']]
ax1.scatter(RGDFT8mm['Pcp'], RGDFT8mm['Pcp_3day'], c=c)
ax2.scatter(RGDFT8mm['Pcp'], RGDFT8mm['Pcp_7day'], c=c)
ax3.scatter(RGDFT8mm['Pcp'], RGDFT8mm['Pcp_14day'], c=c)
ax4.scatter(RGDFT8mm['Pcp'], RGDFT8mm['Pcp_28day'], c=c)

ax.set_title('Daily Rainfall vs antecedent rainfall from Rain Gauges 2001-2017')
ax.set_xlabel('Daily Rainfall (mm)')
ax.set_ylabel('Antecedent rainfall (mm)')
ax.set_yticklabels([])
ax.set_xticklabels([])

ax1.set_title('3 Day')
ax2.set_title('7 Day')
ax3.set_title('14 Day')
ax4.set_title('28 Day')

我在其他地方找不到任何有用的信息。有什么想法吗?

谢谢!

更新:对糟糕的原始结构表示歉意,我在FYI上方添加了数据结构。

2 个答案:

答案 0 :(得分:1)

首先,在不知道数据帧中数据结构的情况下很难说出具体的东西,因此请考虑发布例如RGDFT8mm.head()

也就是说,我至少从您的代码中看到,您已经在一个数据帧中混合了红色和蓝色数据,而没有在散点图之前对其进行分组(=分离)。因此,一个散布命令同时包含两种颜色,因此不可能在前景中获得一种颜色。 如果您进行重组以使每个散点图命令仅绘制一种颜色,则每个散点图都会绘制在前一个颜色的顶部,此外,您可以使用zorder kwarg自行定义每个数据集的层将。

对于分组,您可以使用RGDFT8mm.groupby('SzT')之类的sth-但是,从此处开始提供有用的提示,我宁愿等待确切地了解您的数据框结构。
但是我的第一个猜测是:

for grpname, grpdata in RGDFT8mm.groupby('SzT'):
    ax1.scatter(grpdata['Pcp'], grpdata['Pcp_3day'])
    ax2.scatter(grpdata['Pcp'], grpdata['Pcp_7day'])
    ax3.scatter(grpdata['Pcp'], grpdata['Pcp_14day'])
    ax4.scatter(grpdata['Pcp'], grpdata['Pcp_28day'])

修改 澄清示例

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

data = lambda n: np.random.lognormal(sigma=.5, size=n)
np.random.seed(42)
df = pd.DataFrame({'Pcp': data(500), 'Pcp_3day': data(500), 'SzT': (np.random.random(500)>.9).astype(int)})
print(df.head())

fig, axs = plt.subplots(2, 2, sharex=True, sharey=True)

szt_hi = df.SzT > 0

axs[0, 0].set_title('plot red before blue')
axs[0, 0].scatter(df.loc[szt_hi, 'Pcp'], df.loc[szt_hi, 'Pcp_3day'], c='r', label='SzT=1')
axs[0, 0].scatter(df.loc[~szt_hi, 'Pcp'], df.loc[~szt_hi, 'Pcp_3day'], c='b', label='SzT=0')
axs[0, 0].legend()

axs[0, 1].set_title('plot blue before red')
axs[0, 1].scatter(df.loc[~szt_hi, 'Pcp'], df.loc[~szt_hi, 'Pcp_3day'], c='b', label='SzT=0')
axs[0, 1].scatter(df.loc[szt_hi, 'Pcp'], df.loc[szt_hi, 'Pcp_3day'], c='r', label='SzT=1')
axs[0, 1].legend()

colors = {0 : 'b', 1 : 'r'}
layer = {0: 1, 1: 0}
axs[1, 0].set_title('plot by looping over groups\n(leading to blue first here)')
for i, (n, g) in enumerate(df.groupby('SzT')):
    axs[1, 0].scatter(g.Pcp, g.Pcp_3day, c=colors[i], label='SzT={}'.format(n))
axs[1, 0].legend()

axs[1, 1].set_title('plot by looping over groups \n(leading to blue first here)\nwith manipulating zorder')
for i, (n, g) in enumerate(df.groupby('SzT')):
    axs[1, 1].scatter(g.Pcp, g.Pcp_3day, c=colors[i], zorder=layer[i], label='SzT={}'.format(n))
axs[1, 1].legend()

plt.show()    

enter image description here


...减少legend的打印次数,就可以遍历所有轴,例如

for a in axs.flatten():
    a.legend()

绘制所有子图之后。

但是,在您的情况下,与我的示例相反,您的传说都将是相同的,因此对于整个人物而言,一个传说会更好。为此,只需使用

fig.legend()

可以使用与轴图例相同的参数进行修改。

答案 1 :(得分:1)

只需设置散点的Alpha。类似于以下代码。当然,您可以使用alpha值。

colors = {0 : (0, 0, 1, 0.3),
          1 : (1, 0, 0, 1.0)}


fig = plt.figure(figsize=(20,10))
ax = fig.add_subplot(111)
ax1 = fig.add_subplot(221)
ax2 = fig.add_subplot(222)
ax3 = fig.add_subplot(223)
ax4 = fig.add_subplot(224)

c = [colors[i] for i in RGDFT8mm['SzT']]
m = [marker[i] for i in RGDFT8mm['SzT']]

ax1.scatter(RGDFT8mm['Pcp'], RGDFT8mm['Pcp_3day'], c=c)
ax2.scatter(RGDFT8mm['Pcp'], RGDFT8mm['Pcp_7day'], c=c)
ax3.scatter(RGDFT8mm['Pcp'], RGDFT8mm['Pcp_14day'], c=c)
ax4.scatter(RGDFT8mm['Pcp'], RGDFT8mm['Pcp_28day'], c=c)

ax.set_title('Daily Rainfall vs antecedent rainfall from Rain Gauges 2001-2017')
ax.set_xlabel('Daily Rainfall (mm)')
ax.set_ylabel('Antecedent rainfall (mm)')
ax.set_yticklabels([])
ax.set_xticklabels([])

ax1.set_title('3 Day')
ax2.set_title('7 Day')
ax3.set_title('14 Day')
ax4.set_title('28 Day')

也只是一个建议:绘制多个图时,请使用plt.subplots()和zip。我发现它整洁而有用。选中this