Выбор размера маркера в Matplotlib

Я делаю разброс с квадратным маркером в matplotlib, как этот:

small_marker ,

Я хочу добиться чего-то вроде этого:

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

Это означает, что мне нужно настроить размер маркера и размер / соотношение фигур таким образом, чтобы между маркерами не было пробелов. Также должен быть маркер на единицу индекса ( x и y – целые числа), поэтому, если y идет от 60 до 100, должно быть 40 маркеров в направлении y . В настоящий момент я настраиваю его вручную. Любая идея о том, что является лучшим способом достичь этого?

Я нашел два способа сделать это:

Первый основан на этом ответе . В основном, вы определяете количество пикселей между соседними точками данных и используете его для установки размера маркера. Размер маркера в scatter задается как площадь.

 fig = plt.figure() ax = fig.add_subplot(111, aspect='equal') # initialize a plot to determine the distance between the data points in pixel: x = [1, 2, 3, 4, 2, 3, 3] y = [0, 0, 0, 0, 1, 1, 2] s = 0.0 points = ax.scatter(x,y,s=s,marker='s') ax.axis([min(x)-1., max(x)+1., min(y)-1., max(y)+1.]) # retrieve the pixel information: xy_pixels = ax.transData.transform(np.vstack([x,y]).T) xpix, ypix = xy_pixels.T # In matplotlib, 0,0 is the lower left corner, whereas it's usually the upper # right for most image software, so we'll flip the y-coords width, height = fig.canvas.get_width_height() ypix = height - ypix # this assumes that your data-points are equally spaced s1 = xpix[1]-xpix[0] points = ax.scatter(x,y,s=s1**2.,marker='s',edgecolors='none') ax.axis([min(x)-1., max(x)+1., min(y)-1., max(y)+1.]) fig.savefig('test.png', dpi=fig.dpi) 

Недостатком этого первого подхода является то, что символы перекрываются. Я не смог найти недостаток в этом подходе. Я мог бы вручную настроить s1 на

 s1 = xpix[1]-xpix[0] - 13. 

чтобы дать лучшие результаты, но я не мог определить логику 13. .

Следовательно, второй подход основан на этом ответе . Здесь индивидуальные квадраты рисуются на участке и соответствующим образом. В некотором роде это ручной график рассеяния (цикл используется для построения фигуры), поэтому в зависимости от набора данных это может занять некоторое время.

Этот подход использует patches вместо scatter , поэтому обязательно включите

 from matplotlib.patches import Rectangle 

Опять же, с теми же точками данных:

 x = [1, 2, 3, 4, 2, 3, 3] y = [0, 0, 0, 0, 1, 1, 2] z = ['b', 'g', 'r', 'c', 'm', 'y', 'k'] # in your case, this is data dx = [x[1]-x[0]]*len(x) # assuming equally spaced data-points # you can use the colormap like this in your case: # cmap = plt.cm.hot fig = plt.figure() ax = fig.add_subplot(111, aspect='equal') ax.axis([min(x)-1., max(x)+1., min(y)-1., max(y)+1.]) for x, y, c, h in zip(x, y, z, dx): ax.add_artist(Rectangle(xy=(xh/2., yh/2.), color=c, # or, in your case: color=cmap(c) width=h, height=h)) # Gives a square of area h*h fig.savefig('test.png') 

Один комментарий к Rectangle : координаты – нижний левый угол, следовательно, xh/2.
Этот подход дает связанные прямоугольники. Если бы я внимательно посмотрел на результат здесь, они все еще, казалось, перекрывались на один пиксель – опять же, я не уверен, что этому может помочь.