有没有办法将matplotlib图旋转45度?

时间:2012-10-11 21:11:07

标签: python matplotlib

我正在寻找一种方法将matplotlib-pyplot(Python库)中生成的绘图旋转45度(例如,如果没有方形的形状,你会有钻石形状),任何人都知道这是否可以做什么?

我能想到的一种方法是对所有数据使用旋转滤镜,使其显示为旋转,但绘图本身仍将保持原始方向。

我希望能够使用matplotlib交互功能,因此保存为图像然后旋转将无法正常工作。

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

5 个答案:

答案 0 :(得分:6)

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

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

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

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

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))

答案 1 :(得分: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

答案 2 :(得分:1)

也许如果你在3D情节中这样做?

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

axes3d.view_init(elev, azim)

答案 3 :(得分:0)

This帖子暗示您只能“手动”执行此操作。

  

可以绘制它,但你必须做所有的事情   手动转换/旋转,包括绘制轴   Line2D实例和标签作为文本实例(参见例如   档案中的“Scatter3D”示例)。没有简单的内置方式   目前这样做。在计划的轴处理重构中,

答案 4 :(得分:0)

你看过PIL吗?

此代码将旋转图像。因此,如果您首先将图表作为图像输出到文件,则可以执行

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