使用Matplotlib绘图结果图像旋转90度 - Python

2 投票
1 回答
1272 浏览
提问于 2025-04-18 08:06

我在使用Matplotlib绘图时,常常遇到这种“问题” (相同的数据保存生成不同的图像 - Python)。举个例子,我用一个numpy数组创建了一个向量场,代码如下:

def generate_divergent_free_component(sigma, x_dim, y_dim, steps):
    divergent_free_vector_field_x = numpy.zeros((steps, steps), float)
    divergent_free_vector_field_y = numpy.zeros((steps, steps), float)

    u0 = numpy.random.uniform()
    x0 = 1.0 + sigma * u0
    y0 = sigma * u0

    dx = x_dim/float(steps)
    dy = y_dim/float(steps)

    for x, y in product(range(steps), range(steps)):
        x_norm = -x_dim/2.0 + x * dx
        y_norm = -y_dim/2.0 + y * dy
        exp0 = -(math.pow(x_norm - x0, 2) + math.pow(y_norm - y0, 2)) / 2.0

        divergent_free_vector_field_x[x, y] = -(x_norm - x0) * math.exp(exp0)
        divergent_free_vector_field_y[x, y] = -(y_norm - y0) * math.exp(exp0)

    return divergent_free_vector_field_x, divergent_free_vector_field_y

我做了一些测试,发现ndarrays是按照行优先的顺序排列的,而我在遍历它们时也是按照这个模式进行的。

但是,当我用Matplotlib绘图时,得到的图像却逆时针旋转了90度。

def plot_streamlines(file_path, x_dim, y_dim, steps, vector_field_x, vector_field_y, scalar_field=None):
    plt.figure()

    y, x = numpy.mgrid[-x_dim/2:x_dim/2:steps*1j, -y_dim/2:y_dim/2:steps*1j]

    plt.figure()

    # x, y : 1d arrays, an evenly spaced grid.
    # u, v : 2d arrays
    # x and y-velocities. Number of rows should match length of y, and the number of columns should match x.
    plt.streamplot(x, y, vector_field_x, vector_field_y, cmap=plt.cm.autumn)
    plt.savefig(file_path + '.png')
    plt.close()

举个例子,我得到了这样的图像:

enter image description here

但我原本期待(还有其他程序,比如Matlab)得到这样的图像(我刚在电脑上旋转了一下,但我期待的那个点正好是下面这张图所圈出的):

enter image description here

所以我在想,Matplotlib是不是按照列优先的顺序来处理数据,或者有什么其他的要求……我只是想搞清楚这个到底是怎么回事。

任何帮助都非常感谢。

提前谢谢大家。

1 个回答

0

问题似乎出在 plt.streamplot 这个函数上,它希望 divergent_free_vector_field 的数组是用 [y, x] 的顺序来索引,而不是 [x, y]

一个好的测试方法是尝试在 xy 中使用不同的步长。这样做时,如果你试图绘图,会出现一个 AssertionError 错误,因为它期望行数和 y 的大小相同,而列数和 x 的大小相同。

试着把它改成这样:

divergent_free_vector_field_x = numpy.zeros((steps_y, steps_x), float)
divergent_free_vector_field_y = numpy.zeros((steps_y, steps_x), float)
...
divergent_free_vector_field_x[y, x] = -(x_norm - x0) * math.exp(exp0)
divergent_free_vector_field_y[y, x] = -(y_norm - y0) * math.exp(exp0)

撰写回答