我用代码创建散点图,本质上,是这样的
cmap = (matplotlib.color.LinearSegmentedColormap.
from_list('blueWhiteRed', ['blue', 'white', 'red']))
fig = matplotlib.figure.Figure(figsize=(4, 4), dpi=72)
ax = fig.gca()
for record in data:
level = record.level # a float in [0.0, 1.0]
marker = record.marker # one of 'o', 's', '^', '*', etc.
ax.scatter(record.x, record.y, marker=marker,
c=level, vmin=0, vmax=1, cmap=cmap, **otherkwargs)
# various settings of ticks, labels, etc. omitted
canvas = matplotlib.backends.backend_agg.FigureCanvasAgg(fig)
fig.set_canvas(canvas)
canvas.print_png('/path/to/output/fig.png')
我的问题是:
我需要在上面的代码中添加什么才能在图的右边缘得到一个垂直的颜色条(用cmap
表示颜色Map表)?
- 注意**:我发现Matplotlib***完全不可理解***,这既适用于它的设计,也适用于它的文档。(不是因为缺乏尝试:我已经投入了大量的时间、精力,甚至一些金钱。)所以我希望有完整的、工作正常的代码(即使它只是一个玩具示例),因为很可能我无法填充省略的细节或修复代码中的bug。
编辑:我修正了上面的"代码草图"中的一个重要遗漏,即每次调用ax.scatter
时指定特定于记录的标记,这就是创建多次调用ax.scatter
的散点图的原因,尽管不可否认,至少可以将调用次数减少到每个标记形状使用一次;例如:
for marker in set(record.marker for record in data):
X, Y, COLOR = zip(*((record.x, record.y, record.level)
for record in data if record.marker == marker))
ax.scatter(X, Y, marker=marker,
c=COLOR, vmin=0, vmax=1, cmap=cmap,
**otherkwargs)
我尝试扩展相同的技巧,将对ax.scatter
的所有调用合并为一个调用(通过传递一个标记序列作为marker
参数),如下所示:
X, Y, COLOR, MARKER = zip(*((record.x, record.y, record.level, record.marker)
for record in data))
ax.scatter(X, Y, marker=MARKER,
c=COLOR, vmin=0, vmax=1, cmap=cmap,
**otherkwargs)
...但这失败了。错误如下所示(修剪一些长路径后):
Traceback (most recent call last):
File "src/demo.py", line 222, in <module>
main()
File "src/demo.py", line 91, in main
**otherkwargs)
File "<abbreviated-path>/matplotlib/axes.py", line 6100, in scatter
marker_obj = mmarkers.MarkerStyle(marker)
File "<abbreviated-path>/matplotlib/markers.py", line 113, in __init__
self.set_marker(marker)
File "<abbreviated-path>/matplotlib/markers.py", line 179, in set_marker
raise ValueError('Unrecognized marker style {}'.format(marker))
ValueError: Unrecognized marker style ('^', 'o', '^', '*', 'o', 's', 'o', 'o', '^', 's', 'o', 'o', '^', '^', '*', 'o', '*', '*', 's', 's', 'o', 's', 'o', '^', 'o', 'o', '*', '^', 's', '^', '^', 's', '*')
AFAICT,tcaswell的配方 * 要求 * 将对ax.scatter
的调用减少到单个调用,但此要求似乎与我对同一散点图中多个标记形状的绝对要求相冲突。
5条答案
按热度按时间qojgxg4l1#
如果您必须为每个集合使用不同的标记,则必须做一些额外的工作,并强制所有
clims
相同(否则它们默认从每个散点图的c
数据的最小值/最大值缩放)。linewidths=0
设置了形状边框的宽度,我发现对于小形状来说,黑色边框会压倒填充的颜色。如果你只需要一个形状,你可以用一个散点图来完成这一切,没有必要为每一次通过你的循环做一个单独的形状。
一旦你把所有的数据都打到一个1D数组中,做散点图,并保留返回值:
然后创建颜色条,并将
scatter
返回的对象作为第一个参数传递。您需要执行此操作,以便颜色栏知道要使用哪个颜色贴图(贴图和范围)。
zu0ti5jz2#
我认为你最好的选择是把你的数据填充到一个Pandas数据框中,然后像这样循环遍历你所有的标记:
v64noz0r3#
我想这应该可以了,我很确定我是从一个matplotlib的烹饪书例子中找到的,但是我现在好像找不到了...
2exbekwf4#
这个问题的答案 * 可以 * 是只绘制一个散点,这样就可以直接创建一个colobar。这涉及到将标记放入由散点后验创建的
PathCollection
中,但它可以很容易地放入一个函数中。这个函数来自另一个问题的my answer,但在这里直接适用。从@PaulH的post获取数据,如下所示
tcomlyy65#
这也可能是一个非常简单的解决方案。