Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/279.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 理解matplotlib verts_Python_Matplotlib_Scatter - Fatal编程技术网

Python 理解matplotlib verts

Python 理解matplotlib verts,python,matplotlib,scatter,Python,Matplotlib,Scatter,我试图在matplotlib中为散点图创建自定义标记,其中标记是具有固定高度和不同宽度的矩形。每个标记的宽度是y值的函数。我试着用它作为模板,假设给verts一个N个2-D元组的列表,它会用对应的第一个值的宽度和第二个值的高度绘制矩形(可能这已经错了,但我怎么才能做到呢?) 我有一个x和y值的列表,每个值都包含以度为单位的角度。然后,我计算每个标记的宽度和高度 field_size = 2. symb_vec_x = [(field_size / np.cos(i * np.pi / 180.)

我试图在matplotlib中为散点图创建自定义标记,其中标记是具有固定高度和不同宽度的矩形。每个标记的宽度是y值的函数。我试着用它作为模板,假设给verts一个N个2-D元组的列表,它会用对应的第一个值的宽度和第二个值的高度绘制矩形(可能这已经错了,但我怎么才能做到呢?)

我有一个x和y值的列表,每个值都包含以度为单位的角度。然后,我计算每个标记的宽度和高度

field_size = 2.
symb_vec_x = [(field_size / np.cos(i * np.pi / 180.)) for i in y]
symb_vec_y = [field_size for i in range(len(y))]
然后建立顶点列表并用

symb_vec = list(zip(symb_vec_x, symb_vec_y))
fig = plt.figure(1, figsize=(14.40, 9.00))
ax = fig.add_subplot(1,1,1)
sc = ax.scatter(ra_i, dec_i, marker='None', verts=symb_vec)
但是结果图是空的,但是没有错误消息。有人能告诉我定义顶点的错误是什么,以及如何做正确的事情吗?
谢谢

如前所述,需要删除'marker='None',然后使用顶点指定矩形的适当方法如下

verts = list(zip([-10.,10.,10.,-10],[-5.,-5.,5.,5]))
ax.scatter([0.5,1.0],[1.0,2.0], marker=(verts,0))
顶点被定义为
([x1,x2,x3,x4],[y1,y2,y3,y4])
,因此必须注意哪些得到减号等

这(verts,0)在文档中被称为

为了向后兼容,也接受形式(verts,0), 但它相当于只提供一组原始顶点的顶点 它定义了形状

然而,我发现仅仅使用
顶点
并不能给出正确的形状

要使流程自动化,您需要执行以下操作

v_val=1.0
h_val=2.0
verts = list(zip([-h_val,h_val,h_val,-h_val],[-v_val,-v_val,v_val,v_val]))
基本示例: *

编辑

个体标记 因此,您需要为每种情况手动创建一个顶点。这显然取决于您希望矩形如何逐点更改。这里有一个例子

import pylab as py
ax = py.subplot(111)


def verts_function(x,y,r):
    # Define the vertex's multiplying the x value by a ratio
    x = x*r
    y = y
    return [(-x,-y),(x,-y),(x,y),(-x,y)]

n=5
for i in range(1,4):
    ax.scatter(i,i, marker=(verts_function(i,i,0.3),0))
    py.show()

在我的简单例子中,我画出点I,I,并在它们周围画矩形。指定顶点标记的方式不直观。在本文中,其描述如下:

顶点
:用于路径顶点的(x,y)对列表。中心 标记位于(0,0)处,并且大小已规格化,以便 创建的路径封装在单元单元中

因此,以下是等效的:

vert = [(-300.0, -1000), (300.0, -1000), (300.0, 1000), (-300.0, 1000)]
vert = [(-0.3, -1), (0.3, -1), (0.3, 1), (-0.3, 1)]
e、 g他们将产生相同的标记。因此,我使用了一个比率,这是你需要做的工作。r(比值)的值将改变哪个轴保持不变


这一切都变得非常复杂,我相信一定有更好的方法来做到这一点

我从matplotlib用户邮件列表的Ryan那里得到了解决方案。它非常优雅,所以我将在这里分享他的例子:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import Rectangle
from matplotlib.collections import PatchCollection

n = 100

# Get your xy data points, which are the centers of the rectangles.
xy = np.random.rand(n,2)

# Set a fixed height
height = 0.02
# The variable widths of the rectangles
widths = np.random.rand(n)*0.1

# Get a color map and make some colors
cmap = plt.cm.hsv
colors = np.random.rand(n)*10.
# Make a normalized array of colors
colors_norm = colors/colors.max()
# Here's where you have to make a ScalarMappable with the colormap
mappable = plt.cm.ScalarMappable(cmap=cmap)
# Give it your non-normalized color data
mappable.set_array(colors)

rects = []
for p, w in zip(xy, widths):
    xpos = p[0] - w/2 # The x position will be half the width from the center
    ypos = p[1] - height/2 # same for the y position, but with height
    rect = Rectangle( (xpos, ypos), w, height ) # Create a rectangle
    rects.append(rect) # Add the rectangle patch to our list

# Create a collection from the rectangles
col = PatchCollection(rects)
# set the alpha for all rectangles
col.set_alpha(0.3)
# Set the colors using the colormap
col.set_facecolor( cmap(colors_norm) )
# No lines
col.set_linewidth( 0 )
#col.set_edgecolor( 'none' )

# Make a figure and add the collection to the axis.
fig = plt.figure()
ax = fig.add_subplot(111)
ax.add_collection(col)
# Add your ScalarMappable to a figure colorbar
fig.colorbar(mappable)
plt.show()

谢谢你,Ryan,以及所有贡献自己想法的人

它必须是marker=None,然后我得到的标记条都是相同宽度的,所以有些东西仍然不起作用。inded
marker='None'
杀死标记,但我认为这不是正确使用顶点。我现在正想弄清楚,但是运气不好。谢谢!我自己也试过了,但我找不到一个全面的概述,说明verts在这种情况下是如何工作的。我不明白为什么它在示例中有效,或者更确切地说,它在使用上的区别是什么。谢谢,这看起来很有希望!为了确保(因为在您的示例中,两个数据点只有一个标记形状,我需要每个数据点的单独矩形大小),您说每个标记是由其自身的四个单独角位置(相对于其x/y中心,x1/y1到x4/y4)定义的?如果我有N个x/y数据点要绘制,并且希望每个点都有自己的标记,那么顶点必须保持这些角坐标的N个元组?在我的例子中,这意味着将y1到y4保持不变,并将x1到x4更改为单个y值的函数,对吗?对我来说这似乎是正确的,因此需要将顶点作为N长度的元组列表。手动执行此操作可能更好。如果这变得很复杂,我个人只会在N上使用for循环,并在每次迭代中设置
h_val
。好的,它不适用于单个标记。我尝试将vert作为N个列表的列表,每个列表包含四个x/y元组,并作为N个元组的列表,每个元组包含四个元组。在这两种情况下,我都会得到错误
assert vertices.ndim==2
,因此我只能给verts两个元素。知道这对N个不同的标记如何工作吗?好的,我建议您手动进行,这有点棘手,需要一些努力。我将更新我的解决方案,因为这里没有太多空间。我已经尝试过类似的方法,但当我在for循环中单独绘制每个数据点时,我看不出有任何方法可以为所有这些应用程序使用颜色映射和颜色栏。有?
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import Rectangle
from matplotlib.collections import PatchCollection

n = 100

# Get your xy data points, which are the centers of the rectangles.
xy = np.random.rand(n,2)

# Set a fixed height
height = 0.02
# The variable widths of the rectangles
widths = np.random.rand(n)*0.1

# Get a color map and make some colors
cmap = plt.cm.hsv
colors = np.random.rand(n)*10.
# Make a normalized array of colors
colors_norm = colors/colors.max()
# Here's where you have to make a ScalarMappable with the colormap
mappable = plt.cm.ScalarMappable(cmap=cmap)
# Give it your non-normalized color data
mappable.set_array(colors)

rects = []
for p, w in zip(xy, widths):
    xpos = p[0] - w/2 # The x position will be half the width from the center
    ypos = p[1] - height/2 # same for the y position, but with height
    rect = Rectangle( (xpos, ypos), w, height ) # Create a rectangle
    rects.append(rect) # Add the rectangle patch to our list

# Create a collection from the rectangles
col = PatchCollection(rects)
# set the alpha for all rectangles
col.set_alpha(0.3)
# Set the colors using the colormap
col.set_facecolor( cmap(colors_norm) )
# No lines
col.set_linewidth( 0 )
#col.set_edgecolor( 'none' )

# Make a figure and add the collection to the axis.
fig = plt.figure()
ax = fig.add_subplot(111)
ax.add_collection(col)
# Add your ScalarMappable to a figure colorbar
fig.colorbar(mappable)
plt.show()