python - 有没有办法在 python matplotlib 中设置特定子图的背景颜色?
问题描述
我想使用 制作一个多重图subplot
,这样一个或多个特定子图的背景颜色与其他子图不同,如下例所示:
请注意,我感兴趣的是设置子图外部补丁的背景颜色,而不是图内部的背景颜色(可以使用 来完成facecolor='gray'
)。这是因为我想绘制密度图,并且想将其中的一些与其他部分区分开来。
我发现了类似的问题,例如每行子图都有不同的背景颜色,但我无法修改代码以便可以将颜色应用于特定的子图(比如(1,2),(1 ,3), (2,1) 和 (2,2) 如上图所示)。
这是一个示例代码:
import numpy as np
import matplotlib.pyplot as plt
fig, subs = plt.subplots(3,3,figsize=(10,10))
images = []
for i in range(3):
for j in range(3):
data = np.random.rand(20,20)
images.append(subs[i, j].imshow(data))
subs[i, j].label_outer()
plt.show()
任何帮助将不胜感激。
解决方案
根据[this post],您可以使用fig.patches.extend
在图形上绘制一个矩形。高zorder
的矩形将位于子图的顶部,低的zorder
可以在后面。
现在,属于子图周围环境的确切区域没有明确定义。一种简单的方法是为每个子图分配相等的空间,但这不适用于共享轴,也不适用于图形边缘附近的空白区域。
示例代码使用不同数量的列和行来确保不会翻转水平和垂直计算。
import numpy as np
import matplotlib.pyplot as plt
fig, subs = plt.subplots(3, 4, figsize=(10, 8))
images = []
for i in range(3):
for j in range(4):
data = np.random.rand(20, 20)
images.append(subs[i, j].imshow(data))
subs[i, j].label_outer()
m, n = subs.shape
for _ in range(50):
i = np.random.randint(m)
j = np.random.randint(n)
color = ['r', 'b', 'g'][np.random.randint(3)]
fig.patches.extend([plt.Rectangle((j / n, (m - 1 - i) / m), 1 / n, 1 / m,
fill=True, color=color, alpha=0.2, zorder=-1,
transform=fig.transFigure, figure=fig)])
plt.show()
另一种方法是使用subs[i, j].get_tightbbox(fig.canvas.get_renderer())
,但该边界框仅包含属于子图的文本,仅此而已。
更复杂的方法是计算相邻子图之间的差异,并使用它来扩大子图轴所占据的区域:
m, n = subs.shape
bbox00 = subs[0, 0].get_window_extent()
bbox01 = subs[0, 1].get_window_extent()
bbox10 = subs[1, 0].get_window_extent()
pad_h = 0 if n == 1 else bbox01.x0 - bbox00.x0 - bbox00.width
pad_v = 0 if m == 1 else bbox00.y0 - bbox10.y0 - bbox10.height
for _ in range(20):
i = np.random.randint(m)
j = np.random.randint(n)
color = ['r', 'b', 'g'][np.random.randint(3)]
bbox = subs[i, j].get_window_extent()
fig.patches.extend([plt.Rectangle((bbox.x0 - pad_h / 2, bbox.y0 - pad_v / 2),
bbox.width + pad_h, bbox.height + pad_v,
fill=True, color=color, alpha=0.2, zorder=-1,
transform=None, figure=fig)])
根据地块的布局,它仍然不完美。该方法可以进一步细化,例如对第一列和最低行进行特殊处理。如果重叠不是问题,边界框也可以通过 的结果来扩展get_tightbbox()
,使用较浅的颜色 和alpha=1
。
这是在四个边都有刻度标签的图的样子:
推荐阅读
- mongodb - 如何使用 struct 使用 mongo-go-driver 的更新功能
- excel - 返回月份数的 VBA 函数
- python - 运行 object_detection/model_main.py 时如何解决“以下类没有真实示例”?
- smalltalk - VisualWorks - 在字符串中查找字符并替换它们
- r - 使用 facet_grid() 创建相等且漂亮的比例中断
- angular - 如果模态中有未保存的更改,如何防止取消模态?
- sprite-kit - 使 SKLabelNode 不透明背景的简单方法?
- debian - Debian/Ubuntu Java 11 java-alternative
- php - 错误:需要支持 FreeType 的 GD PHP 扩展或支持 PNG 的 ImageMagick PHP 扩展
- javascript - 如何在 html 中的元素之前添加单数关闭 div '