[英]Python scatter plot. Size and style of the marker
I have a set of data that I want to show as a scatter plot. 我有一组数据要显示为散点图。 I want each point to be plotted as a square of size
dx
. 我希望将每个点绘制为大小为
dx
的正方形。
x = [0.5,0.1,0.3]
y = [0.2,0.7,0.8]
z = [10.,15.,12.]
dx = [0.05,0.2,0.1]
scatter(x,y,c=z,s=dx,marker='s')
The problem is that the size s
that the scatter function read is in points^2. 问题是分散函数读取的大小为
s
^ 2。 What I'd like is having each point represented by a square of area dx^2, where this area is in 'real' units, the plot units. 我想要的是每个点由面积dx ^ 2的平方表示,其中该区域是“实际”单位,即绘图单位。 I hope you can get this point.
我希望你能明白这一点。
I also have another question. 我还有另一个问题。 The scatter function plots the markers with a black border, how can I drop this option and have no border at all?
散点函数用黑色边框绘制标记,如何删除此选项并且根本没有边框?
Translate from user data coordinate system to display coordinate system. 从用户数据坐标系转换为显示坐标系。
and use edgecolors='none' to plot faces with no outlines. 并使用edgecolors ='none'绘制没有轮廓的面。
import numpy as np
fig = figure()
ax = fig.add_subplot(111)
dx_in_points = np.diff(ax.transData.transform(zip([0]*len(dx), dx)))
scatter(x,y,c=z,s=dx_in_points**2,marker='s', edgecolors='none')
If you want markers that resize with the figure size, you can use patches: 如果您想要使用图形大小调整大小的标记,可以使用修补程序:
from matplotlib import pyplot as plt
from matplotlib.patches import Rectangle
x = [0.5, 0.1, 0.3]
y = [0.2 ,0.7, 0.8]
z = [10, 15, 12]
dx = [0.05, 0.2, 0.1]
cmap = plt.cm.hot
fig = plt.figure()
ax = fig.add_subplot(111, aspect='equal')
for x, y, c, h in zip(x, y, z, dx):
ax.add_artist(Rectangle(xy=(x, y),
color=cmap(c**2), # I did c**2 to get nice colors from your numbers
width=h, height=h)) # Gives a square of area h*h
plt.show()
Note that: 注意:
(x,y)
. (x,y)
为中心。 x,y are actually the coords of the square lower left. (x + dx/2, y + dx/2)
. (x + dx/2, y + dx/2)
。 Finally for your second question. 最后是你的第二个问题。 You can get the border of the scatter marks out using the keyword arguments
edgecolor
or edgecolors
. 您可以使用关键字参数
edgecolor
或edgecolors
来获取散点图的边框。 These are a matplotlib color argument or a sequence of rgba tuples, respectively. 它们分别是matplotlib颜色参数或rgba元组序列。 If you set the parameter to 'None', borders are not draw.
如果将参数设置为“无”,则不绘制边框。
I think we can do it better with a collection of patches. 我想我们可以通过一系列补丁来做得更好。 According to documents:
根据文件:
This (PatchCollection) makes it easier to assign a color map to a heterogeneous collection of patches.
这个(PatchCollection)可以更容易地将颜色映射分配给异构的补丁集合。
This also may improve plotting speed , since PatchCollection will draw faster than a large number of patches.
这也可以提高绘图速度 ,因为PatchCollection将比大量补丁绘制得更快。
Suppose you want to plot a scatter of circles with given radius in data unit: 假设您要在数据单元中绘制具有给定半径的圆的散布:
def circles(x, y, s, c='b', vmin=None, vmax=None, **kwargs):
"""
Make a scatter of circles plot of x vs y, where x and y are sequence
like objects of the same lengths. The size of circles are in data scale.
Parameters
----------
x,y : scalar or array_like, shape (n, )
Input data
s : scalar or array_like, shape (n, )
Radius of circle in data unit.
c : color or sequence of color, optional, default : 'b'
`c` can be a single color format string, or a sequence of color
specifications of length `N`, or a sequence of `N` numbers to be
mapped to colors using the `cmap` and `norm` specified via kwargs.
Note that `c` should not be a single numeric RGB or RGBA sequence
because that is indistinguishable from an array of values
to be colormapped. (If you insist, use `color` instead.)
`c` can be a 2-D array in which the rows are RGB or RGBA, however.
vmin, vmax : scalar, optional, default: None
`vmin` and `vmax` are used in conjunction with `norm` to normalize
luminance data. If either are `None`, the min and max of the
color array is used.
kwargs : `~matplotlib.collections.Collection` properties
Eg. alpha, edgecolor(ec), facecolor(fc), linewidth(lw), linestyle(ls),
norm, cmap, transform, etc.
Returns
-------
paths : `~matplotlib.collections.PathCollection`
Examples
--------
a = np.arange(11)
circles(a, a, a*0.2, c=a, alpha=0.5, edgecolor='none')
plt.colorbar()
License
--------
This code is under [The BSD 3-Clause License]
(http://opensource.org/licenses/BSD-3-Clause)
"""
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import Circle
from matplotlib.collections import PatchCollection
if np.isscalar(c):
kwargs.setdefault('color', c)
c = None
if 'fc' in kwargs: kwargs.setdefault('facecolor', kwargs.pop('fc'))
if 'ec' in kwargs: kwargs.setdefault('edgecolor', kwargs.pop('ec'))
if 'ls' in kwargs: kwargs.setdefault('linestyle', kwargs.pop('ls'))
if 'lw' in kwargs: kwargs.setdefault('linewidth', kwargs.pop('lw'))
patches = [Circle((x_, y_), s_) for x_, y_, s_ in np.broadcast(x, y, s)]
collection = PatchCollection(patches, **kwargs)
if c is not None:
collection.set_array(np.asarray(c))
collection.set_clim(vmin, vmax)
ax = plt.gca()
ax.add_collection(collection)
ax.autoscale_view()
if c is not None:
plt.sci(collection)
return collection
All the arguments and keywords (except marker
) of scatter
function would work in similar way. scatter
函数的所有参数和关键字( marker
除外)都可以以类似的方式工作。 I've write a gist including circles , ellipses and squares / rectangles . 我写了一个要点,包括圆形 , 椭圆形和正方形 / 矩形 。 If you want a collection of other shape, you could modify it yourself.
如果你想要一个其他形状的集合,你可以自己修改它。
If you want to plot a colorbar just run colorbar()
or pass the returned collection object to colorbar
function. 如果要绘制颜色条,只需运行
colorbar()
或将返回的集合对象传递给colorbar
函数。
An example: 一个例子:
from pylab import *
figure(figsize=(6,4))
ax = subplot(aspect='equal')
#plot a set of circle
a = arange(11)
out = circles(a, a, a*0.2, c=a, alpha=0.5, ec='none')
colorbar()
#plot one circle (the lower-right one)
circles(1, 0, 0.4, 'r', ls='--', lw=5, fc='none', transform=ax.transAxes)
xlim(0,10)
ylim(0,10)
Output: 输出:
To make this Python 3 compatible, I added the following snippet of code 为了使Python 3兼容,我添加了以下代码片段
try:
basestring
except NameError:
basestring = str
from 从
How to check if variable is string with python 2 and 3 compatibility 如何检查变量是否是python 2和3兼容性的字符串
This is necessary because basestring
is not available in Python 3. In Python 2, the purpose of basestring
was to include both str
and unicode
. 这是必要的,因为在Python 3中没有
basestring
。在Python 2中, basestring
的目的是包括str
和unicode
。 In Python 3 there is no distinction between str
and unicode
, and it's just str
. 在Python 3中,
str
和unicode
之间没有区别,它只是str
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.