【问题标题】:How do you get the marker squares to be exact squares with matplotlib?您如何使用 matplotlib 使标记正方形成为精确的正方形?
【发布时间】:2015-05-08 10:28:22
【问题描述】:

首先,重要的是我使用 plt.scatter 而不是通过迭代点(补丁)来执行此操作,因为对于我的真实数据,我有大量的数据点。问题是如何使用 plt.scatter 解决这个问题并找到正确的标记大小。

通过这个小例子,我想实现以下目标:

  1. 对于我的 16 个数据点中的每一个,图片上的一个正方形应以特定于该点的颜色绘制。
  2. 根据 figsize,我需要计算出标记需要的确切数据点数。

我的策略: a) 使用 ax.transData.transform 获取 0,0, 0,1, 0,2 的像素值 和 1,0, 2,0, 3,0 来验证距离是否相等。 b)将宽度乘以高度以获得我需要的标记的大小。 c) 从像素转换为点。 d) 将此标记输入 plt.scatter。

import numpy as np
import matplotlib.pyplot as plt

xdim = 4
figs = 5
dpi = 100

fig = plt.figure(num=None, figsize=(figs, figs), dpi=dpi, facecolor='w', edgecolor='k')
plt.xlim((-1,5))
plt.ylim((-1,5))

ax = fig.add_subplot(111)
x = np.arange(0+.5, xdim+.5, 1)
y = np.arange(0+.5, xdim+.5, 1)

X, Y = np.meshgrid(x, y)

Z= np.random.rand(xdim*xdim,3)

x_diff = np.diff(ax.transData.transform([(0,0),(0,1),(0,2),(0,3),(0,4)]),axis=0)
y_diff = np.diff(ax.transData.transform([(0,0),(1,0),(2,0),(3,0),(4,0)]),axis=0)

print(x_diff,y_diff)

x_avg = np.average(x_diff[0,1])
y_avg = np.average(y_diff[1,0])

print(x_avg,y_avg)

marker_pixels = x_avg*y_avg
marker_points = (marker_pixels*72)/dpi

print marker_points

plt.scatter(X,Y,c=Z, s=marker_points, marker='s', edgecolors=None)

plt.savefig('foo.png', dpi=dpi)

但是,在这个例子中,我得到的结果是 66.666(事实!)和 64.58,即不是正方形。当我将两者相乘时,转换并输入 plt.scatter 我得到这个图像:

如您所见,正方形不是正方形,并且不完全填充从 0,0 到 1,1 等的正方形。如果您使用 fig.show() 这会更清楚。

这个近似解还可以,因为网格很大,看起来还不错,但我想知道如何才能准确地解决这个问题。如何确保标记准确地放置在它应该适合的正方形内,从左下正方形的两个轴上的 0,1 填充?

【问题讨论】:

  • 在我看来,这些只是有点太大并且与顶部的 (4,4) 重叠,从而产生不规则的可见斑块。如果你把它们做成半透明的会是什么样子?
  • 它们会稍微重叠。这里最大的问题实际上是来自 ax.transData.transform() 的报告。为什么 x 轴和 y 轴上的距离不同?
  • 您是否在任何地方设置了aspect=square?有时是equal
  • 我只有我展示的 MWE,我应该把aspect=equal放在哪里?在调用 plt.figure?
  • aspect 属于轴,而不是图形;查看help(plt.axis)

标签: python matplotlib


【解决方案1】:

一般的答案可能是补丁,而不是标记方块,不管它有多慢。但是,使用您展示的示例的网格特性,有一种更简单的方法,您仍然可以对其进行其他绘图:

import matplotlib.pyplot as plt
from matplotlib import cm
import numpy.random as nr
quilt = nr.random((4,4))


plt.imshow(quilt, interpolation='none', aspect='equal', cmap=cm.jet)
plt.scatter([1,2,3],[3,0,1])
plt.plot([0,1,1.4, 2.3, 3.5],[0,1,2,3,2])
plt.show()

您可以更改轴刻度以表示您的数据单位,自定义颜色图以使缺失数据具有透明方块,将 imshow 作为子图嵌入另一个图中,等等。

【讨论】:

  • 这正是我想要的。在我的真实数据中,我将颜色代码编码为 4 维向量,然后我需要在每个正方形内进行注释。将我的 (xdim*xdim,4) 矩阵重塑为 (xdim,xdim,4) 非常适合作为 imshow() 的输入。 (现在我必须做一些像素运算来找出偏移文本的程度)。
猜你喜欢
  • 2023-02-01
  • 2011-09-27
  • 2016-04-06
  • 1970-01-01
  • 2020-01-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多