Matplotlib: вывести на передний план один набор данных графика рассеяния - PullRequest
0 голосов
/ 08 ноября 2018

У меня есть серия вспомогательных участков с красными и синими маркерами, меня больше всего интересуют красные маркеры, поэтому я хочу вывести их на передний план:

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 голосов
/ 09 ноября 2018

Просто установите альфа точек разброса. Что-то вроде следующего кода. Конечно, вы можете играть с альфа-значениями.

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 при построении нескольких графиков. Я нахожу это аккуратным и полезным. Отметьте это

0 голосов
/ 08 ноября 2018

Поначалу довольно сложно сказать конкретное, не зная структуры ваших данных в кадре данных, поэтому, пожалуйста, рассмотрите возможность публикации, например. RGDFT8mm.head()

Тем не менее, я вижу, по крайней мере, из вашего кода, что вы смешали красные и синие данные в одном кадре данных без группировки (= разделения) перед построением точечной диаграммы. Поэтому одна команда разброса содержит оба цвета, что делает невозможным получение одного цвета на переднем плане.
Если вы реструктурируете так, что каждая команда разброса отображает только один цвет, каждый разброс будет нанесен поверх предыдущего, и, кроме того, вы можете использовать zorder kwarg для определения слоя каждого набора данных по собственному желанию.

Для группировки вы можете использовать sth, как RGDFT8mm.groupby('SzT') - однако, чтобы дать полезные подсказки, я бы подождал, чтобы точно знать структуру вашего фрейма данных.
Но мое первое предположение будет:

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()

изменяемый с такими же параметрами, как легенды оси.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...