Zau*_*aus 3 python matplotlib legend colormap
当前情况:
我有多组线,其中同一组中的线会根据某些特定于组的参数而变化。我根据此参数为同一组内的每行分配一种颜色表中的颜色,并对每个组使用不同的颜色表。
现在,我想在图上添加图例,每组线有一个条目。

仅适用于一组线的解决方案:
如果我只有一组线,则最好的标注方法是按照答案的建议添加色条:Matplotlib:将色条添加到不可映射的对象。
如何最好地对多组线执行此操作?
因为我有多组这样的线,所以我不想为每个新参数添加一个颜色条。相反,我宁愿在图例中放置填充有对应色图的色块(作为一种迷你色条)。
最小的工作示例:
在下面的内容中,您可以找到当前情况的最小工作示例。但是请注意,我在很大程度上简化了隐藏参数依赖性的行的计算。因此,我的“参数” param就是我要遍历的索引。我的实际代码根据具有更复杂功能的模型参数来计算x和y值。因此,param_max此处的最大值对于每组线都是相同的,尽管实际上并非如此。
import numpy as np
import matplotlib.pyplot as plt
x_array = np.linspace(1, 10, 10)
y_array = x_array
param_max = x_array.size
cmaps = [plt.cm.spring, plt.cm.winter] # set of colormaps
# (as many as there are groups of lines)
plt.figure()
for param, (x, y) in enumerate(zip(x_array, y_array)):
x_line1 = np.linspace(x, 1.5 * x, 10)
y_line1 = np.linspace(y**2, y**2 - x, 10)
x_line2 = np.linspace(1.2 * x, 1.5 * x, 10)
y_line2 = np.linspace(2 * y, 2 * y - x, 10)
# plot lines with color depending on param using different colormaps:
plt.plot(x_line1, y_line1, c=cmaps[0](param / param_max))
plt.plot(x_line2, y_line2, c=cmaps[1](param / param_max))
plt.show()
Run Code Online (Sandbox Code Playgroud)
这将产生上面显示的图。
由于找不到任何直接在stackoverflow上回答此问题的方法,因此我尝试自己找到一种解决方案,您可以在答案部分中找到它。如果有更直接/合适的方法,我将很高兴知道。
在这种情况下,我将ImportanceOfBeingErnest的答案的解决方案调整为“用双色矩形为图例创建matplotlib mpatches”。链接在那里,在matplotlib图例指南中有关实现自定义图例处理程序的部分中的说明特别有用。
结果:

解:
我创建了HandlerColormap从matplotlib的图例处理程序基类派生的类HandlerBase。HandlerColormap以一个颜色图和一些条纹作为参数。
对于参数,应给出cmapmatplotlib 颜色图实例。
该参数num_stripes确定图例补丁中颜色渐变的(非)连续性。
按照HandlerBase我的指示,我create_artist使用给定的维度覆盖了它的方法,因此应该按字体大小自动缩放代码。在这种新create_artist方法中,我创建了Rectangles根据输入颜色图着色的多个条纹(苗条matplotlib )。
码:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import Rectangle
from matplotlib.legend_handler import HandlerBase
class HandlerColormap(HandlerBase):
def __init__(self, cmap, num_stripes=8, **kw):
HandlerBase.__init__(self, **kw)
self.cmap = cmap
self.num_stripes = num_stripes
def create_artists(self, legend, orig_handle,
xdescent, ydescent, width, height, fontsize, trans):
stripes = []
for i in range(self.num_stripes):
s = Rectangle([xdescent + i * width / self.num_stripes, ydescent],
width / self.num_stripes,
height,
fc=self.cmap((2 * i + 1) / (2 * self.num_stripes)),
transform=trans)
stripes.append(s)
return stripes
x_array = np.linspace(1, 10, 10)
y_array = x_array
param_max = x_array.size
cmaps = [plt.cm.spring, plt.cm.winter] # set of colormaps
# (as many as there are groups of lines)
plt.figure()
for param, (x, y) in enumerate(zip(x_array, y_array)):
x_line1 = np.linspace(x, 1.5 * x, 10)
y_line1 = np.linspace(y**2, y**2 - x, 10)
x_line2 = np.linspace(1.2 * x, 1.5 * x, 10)
y_line2 = np.linspace(2 * y, 2 * y - x, 10)
# plot lines with color depending on param using different colormaps:
plt.plot(x_line1, y_line1, c=cmaps[0](param / param_max))
plt.plot(x_line2, y_line2, c=cmaps[1](param / param_max))
cmap_labels = ["parameter 1 $\in$ [0, 10]", "parameter 2 $\in$ [-1, 1]"]
# create proxy artists as handles:
cmap_handles = [Rectangle((0, 0), 1, 1) for _ in cmaps]
handler_map = dict(zip(cmap_handles,
[HandlerColormap(cm, num_stripes=8) for cm in cmaps]))
plt.legend(handles=cmap_handles,
labels=cmap_labels,
handler_map=handler_map,
fontsize=12)
plt.show()
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
380 次 |
| 最近记录: |