【问题标题】:Is there a way to rotate a matplotlib plot by 45 degrees?有没有办法将 matplotlib 图旋转 45 度?
【发布时间】:2017-07-20 01:58:50
【问题描述】:

我正在寻找一种将 matplotlib-pyplot(Python 库)中生成的绘图旋转 45 度的方法(例如,您可以使用菱形而不是正方形),任何人都知道这是否可以完成了吗?

我能想到的一种方法是对所有数据使用旋转过滤器,使其看起来旋转,但绘图本身仍将保持原始方向。

我希望能够使用 matplotlib 的交互功能,所以保存为图像然后旋转是行不通的。

另外,我想使用 pyplot 函数来绘制绘图,因此使用不同的库进行绘图并不是一个理想的解决方案。

【问题讨论】:

  • 我能问一下为什么吗?如果是为了外部的东西,您可能可以将图形保存为 png,然后使用 imagemagik 或相关程序来旋转保存的图像。
  • @tcaswell 是可能的,但我不想保存到图形,因为我想以交互方式使用 matplotlib 显示功能(平移、缩放、光标/数据协调等)。当然,图书馆内的解决方案会更方便。

标签: python matplotlib


【解决方案1】:

好的,所以目前我发现的唯一部分解决方案是对绘图应用旋转。这允许使用 matplotlib/pyplot 提供的交互界面。

对于像 plot() 和 scatter() 这样的点图,这是微不足道的,但我对旋转 imshow() 特别感兴趣。 This 链接讨论了可能用于此任务的 transform 关键字,但它显然不起作用。

幸运的是,我找到了使用 pcolormesh() 的解决方法。 pcolormesh() 绘制四边形网格并允许您指定角坐标。因此,答案是仅将相关变换应用于角坐标。但是请注意, pcolormesh() 的工作方式与 imshow 有点不同 - 它绘制您的矩阵翻转。

我在网上的任何地方都没有看到这个解决方案,所以这里有一些 pcolormesh()/imshow() 旋转 45 度的代码:

import matplotlib.pyplot as plt
import numpy as np

def pcolormesh_45deg(C):

    n = C.shape[0]
    # create rotation/scaling matrix
    t = np.array([[1,0.5],[-1,0.5]])
    # create coordinate matrix and transform it
    A = np.dot(np.array([(i[1],i[0]) for i in itertools.product(range(n,-1,-1),range(0,n+1,1))]),t)
    # plot
    plt.pcolormesh(A[:,1].reshape(n+1,n+1),A[:,0].reshape(n+1,n+1),np.flipud(C))

【讨论】:

  • 我知道这是一篇很老的帖子,但它对我非常有用。我唯一的问题是如何使坐标位于箱的末端而不是它们的中心?
  • C 是一个对称矩阵。
【解决方案2】:

基于Bitwise anwer,可以使用如下函数:

def pcolormesh_45deg(C, ax=None, xticks=None, xticklabels=None, yticks=None,
                     yticklabels=None, aspect='equal', rotation=45,
                     *args, **kwargs):
    import itertools

    if ax is None:
        ax = plt.gca()
    n = C.shape[0]
    # create rotation/scaling matrix
    t = np.array([[1, .5], [-1, .5]])
    # create coordinate matrix and transform it
    product = itertools.product(range(n, -1, -1), range(0, n + 1, 1))
    A = np.dot(np.array([(ii[1], ii[0]) for ii in product]), t)
    # plot
    ax.pcolormesh((2 * A[:, 1].reshape(n + 1, n + 1) - n),
                  A[:, 0].reshape(n + 1, n + 1),
                  np.flipud(C), *args, **kwargs)

    xticks = np.linspace(0, n - 1, n, dtype=int) if xticks is None else xticks
    yticks = np.linspace(0, n - 1, n, dtype=int) if yticks is None else yticks

    if xticks is not None:
        xticklabels = xticks if xticklabels is None else xticklabels
        for tick, label, in zip(xticks, xticklabels):
            ax.scatter(-n + tick + .5, tick + .5, marker='x', color='k')
            ax.text(-n + tick + .5, tick + .5, label,
                    horizontalalignment='right', rotation=-rotation)
    if yticks is not None:
        yticklabels = yticks if yticklabels is None else yticklabels
        for tick, label, in zip(yticks, yticklabels):
            ax.scatter(tick + .5, n - tick - .5, marker='x', color='k')
            ax.text(tick + .5, n - tick - .5, label,
                    horizontalalignment='left', rotation=rotation)

    if aspect:
        ax.set_aspect(aspect)
    ax.set_xlim(-n, n)
    ax.set_ylim(-n, n)
    ax.plot([-n, 0, n, 0., -n], [0, n, 0, -n, 0], color='k')
    ax.axis('off')
    return ax

【讨论】:

    【解决方案3】:

    如果你是在 3D 绘图上做的话?

    http://matplotlib.1069221.n5.nabble.com/How-to-rotate-a-3D-plot-td19185.html

    axes3d.view_init(elev, azim)

    【讨论】:

    • 这是可能的,不过我必须使用 mplot3d 的绘图函数——希望它们具有与 pyplot 函数相同的功能。谢谢。
    • 查看 mplot3d,我发现它的 2d 绘图比 pyplot 更受限制。所以我更喜欢一个可以操纵我的 pyplot 绘图的解决方案。
    • 只是好奇...为什么需要旋转?我觉得这里有一些数据可视化技术可供我学习。 :]
    • altendky - 我有一个数据集,它为某个向量上的每对位置提供一个值。这被可视化为一个对称矩阵(或三角矩阵),最自然的定位这个矩阵的方法是旋转 45 度,使对角线是水平的。这是显示此类数据的常用方式。
    【解决方案4】:

    你看过PIL吗?

    此代码将旋转图像。因此,如果您首先将绘图作为图像输出到文件中,那么您可以这样做

    import Image
    img = Image.open("plot.jpg")
    img2 = img.rotate(45)
    img2.show()
    img2.save("rotate.jpg")
    

    【讨论】:

    • 如果您不关心旋转的轴(或者如果您不必担心),则此方法有效
    • 见我上面对 tcaswell 的回答,我想要 matplotlib 中的交互功能,所以这个用处不大。
    【解决方案5】:

    This 帖子建议您只能“手动”完成。

    可以画出来,但你必须做所有 手动转换/旋转,包括将轴绘制为 Line2D 实例和标签作为 Text 实例(参见例如 档案中的“Scatter3D”示例)。没有简单的内置方法 去做,目前。在轴处理的计划重构中,

    【讨论】:

    • 谢谢,虽然那篇文章是从 2005 年开始的,所以从那以后的 7 年多里有可能发生了变化......
    • @我同意,我希望你能找到一些东西,我很乐意出错:)
    猜你喜欢
    • 2020-10-03
    • 2011-09-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多