2012-10-11 83 views
3

我正在寻找一种将matplotlib-pyplot(Python库)中生成的图形旋转45度的方法(例如,以代替方形的形状,例如您将拥有菱形形状),任何人都知道这是否可以完成?有没有办法将matplotlib图形旋转45度?

我能想到的一种方法是对所有数据使用旋转过滤器,以便它看起来旋转,但是然后绘图本身仍然处于原始方向。

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

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

+1

请问为什么?如果是为了某种外在的东西,你可能能够将这个图形保存为png,然后使用imagemagik或相关程序来旋转保存的图像。 – tacaswell

+2

@ tcaswell这是可能的,但我不想保存到一个数字,因为我想交互使用matplotlib显示功能(平移,缩放,光标/数据协调等)。当然,一个库内解决方案会更方便。 – Bitwise

回答

5

好了,所以目前唯一的解决部分问题,我发现是一个旋转适用于情节。这允许使用matplotlib/pyplot提供的交互界面。

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

幸运的是,我找到了一个使用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)) 
+0

我知道这是一个非常古老的帖子,但它对我来说非常有用。我唯一的问题是如何使坐标位于垃圾箱的末端而不是其中心? – Phlya

0

This帖子建议你只能“手工”操作。

它可以绘制它,但你必须做的所有 转换/手动旋转,包括绘制坐标轴为 的Line2D实例和标签的文字实例(例如见 “Scatter3D”的例子在档案中)。目前没有简单的内置方法来执行此操作。在计划的轴处理重构中,

+0

谢谢,虽然那篇文章是从2005年开始的,所以有机会在7年以后发生了变化...... – Bitwise

+0

@我同意,我希望你找到一些东西,我会很高兴出错:) – root

1

也许如果你在3D图上做它?

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

axes3d.view_init(elev, azim)

+0

这是可能的,但我不得不使用mplot3d的绘图功能 - 希望它们具有与pyplot函数相同的功能。谢谢。 – Bitwise

+0

看着mplot3d,我发现它在二维绘图中比pyplot更受限制。所以我更喜欢一个解决方案来操纵我的情节,通过pyplot。 – Bitwise

+0

只是好奇......为什么需要旋转?我觉得这里有一些数据可视化技术供我学习。 :] – altendky

0

你有没有看着PIL

此代码将旋转图像。所以,如果你第一次输出的打印到文件作为图像,你可以再做

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

如果你不关心坐标轴旋转(或者如果你没有他们担心的话),这可以工作 – mrchampe

+0

查看我对tcaswell的回答,我想要matplotlib中的交互功能,所以这不太有用。 – Bitwise

2

基础上按位前面回答,您可以使用以下功能:

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 
相关问题