График рассеяния с альфой, все еще непрозрачный по областям, где пятна плотны

У меня есть график рассеяния, который отображает очень большое количество точек из двух разных наборов данных. В некоторых областях существует огромное количество точек, так что даже при очень низкой альфа (например, альфа = 0,1) вы не можете видеть сквозь массу. Но при этом альфа вы едва можете увидеть точки в разреженных регионах. Есть ли способ связать альфу для уложенных точек или каким-то образом сделать фон видимым в плотных областях, не вымывая разреженные регионы?

Фрагмент кода выглядит так:

# Code to populate the datasets not included. fig, ax = plt.subplots() ax.scatter(x1, y1, s=12, color='red') ax.scatter(x2, y2, s=12, color='blue', alpha=0.1) # Plus code to do xlabels and such not included. 

для производства:

введите описание изображения здесь

Как вы можете видеть, трудно увидеть границы нижней красной ноги и по-прежнему сделать верхнюю синюю ногу.

Есть ли способ создать этот эффект?

Заранее спасибо.

РЕДАКТИРОВАТЬ

Одно хорошее предложение – использовать гексбин вместо разброса. Это кажется многообещающим, но цвета все еще не сочетаются красиво. Например,

 ax.hexbin(x1, y1, cmap='Reds', mincnt=1, vmax=100) ax.hexbin(x2, y2, cmap='Blues', mincnt=1, vmax=50, alpha=0.8, linewidths=0) 

выходы:

введите описание изображения здесь

Было бы очень приятно, чтобы эти блюзы и красные слились. Может быть, каждый пиксель может иметь значение R из одного набора данных и значение B из другого набора данных или что-то еще? Но это не похоже на вариант в hexbin.

РЕДАКТИРОВАТЬ

После применения ответа Томиллио:

введите описание изображения здесь

Спасибо, я думаю, что это выглядит лучше оригинала.

1) Чтобы улучшить график гексбина, вы можете использовать опцию bins = 'log'. Это вычисляет цвет гексагонального биннинга логарифмически, эффективно делая более низкие числа торчат лучше по сравнению с высокими.

2) Рассчитайте плотность для каждого набора данных самостоятельно. И из обеих плотностей генерирует цвет, например, позволяя одной плотности влиять на красный, а другой – на синий. Выделите результат, используя imshow.

Что-то вроде

 import matplotlib.pyplot as plt import numpy as np import itertools x1 = np.random.binomial(5100,0.5,51100) y1 = np.random.binomial(5000,0.7,51100) x2 = np.random.binomial(5000,0.5,51100) y2 = np.random.binomial(5000,0.7,51100) xmin,xmax,xnum = 2350,2700,50 ymin,ymax,ynum = 3350,3700,50 xx,yy=np.mgrid[xmin:xmax:xnum*1j,ymin:ymax:ynum*1j] def closest_idx(x,y): idcs = np.argmin((xx-x)**2 + (yy-y)**2) i_x,i_y = np.unravel_index(idcs, (xnum,ynum) ) return i_x,i_y def calc_count( xdat,ydat ): ct = np.zeros_like(xx) for x,y in itertools.izip(xdat,ydat): ix,iy = closest_idx(x,y) ct [ix,iy] += 1 return ct ct1 = calc_count( x1,y1 ) ct2 = calc_count( x2,y2 ) def color_mix( c1 , c2 ): cm=np.empty_like(c1) for i in [0,1,2]: cm[i] = (c1[i]+c2[i])/2. return cm dens1 = ct1 / np.max(ct1) dens2 = ct2 / np.max(ct2) ct1_color = np.array([1+0*dens1 , 1-dens1 , 1-dens1 ]) ct2_color = np.array([1-dens2 , 1-dens2 , 1+0*dens2]) col = color_mix( ct1_color , ct2_color ) col = np.transpose( col, axes=(2,1,0)) plt.imshow( col , interpolation='nearest' ,extent=(xmin,xmax,ymin,ymax),origin='lower') plt.show()