Python 在matplotlib中变换整个轴(或散点图)

Python 在matplotlib中变换整个轴(或散点图),python,matplotlib,transform,Python,Matplotlib,Transform,我正在用下面的代码绘制一些数据的均值和方差的变化 import matplotlib.pyplot as pyplot import numpy vis_mv(data, ax = None): if ax is None: ax = pyplot.gca() cmap = pyplot.get_cmap() colors = cmap(numpy.linspace(0, 1, len(data))) xs = numpy.arange(len(data))

我正在用下面的代码绘制一些数据的均值和方差的变化

import matplotlib.pyplot as pyplot
import numpy

vis_mv(data, ax = None):
    if ax is None: ax = pyplot.gca()
    cmap = pyplot.get_cmap()
    colors = cmap(numpy.linspace(0, 1, len(data)))

    xs = numpy.arange(len(data)) + 1
    means = numpy.array([ numpy.mean(x) for x in data ])
    varis = numpy.array([ numpy.var(x) for x in data ])
    vlim = max(1, numpy.amax(varis))

    # variance
    ax.imshow([[0.,1.],[0.,1.]],
        cmap = cmap, interpolation = 'bicubic',
        extent = (1, len(data), -vlim, vlim), aspect = 'auto'
    )
    ax.fill_between(xs, -vlim, -varis, color = 'white')
    ax.fill_between(xs, varis, vlim, color = 'white')

    # mean
    ax.plot(xs, means, color = 'white', zorder = 1)
    ax.scatter(xs, means, color = colors, edgecolor = 'white', zorder = 2)

    return ax
这非常好: 但是现在我想能够以一种垂直的方式使用这种可视化,作为一种高级的颜色条,类似于另一个情节旁边的东西。我希望能够旋转整个轴及其所有内容, 但我只能找到,这也不是一个确切的答案。因此,我试着自己做如下:

from matplotlib.transforms import Affine2D

ax = vis_mv()
r = Affine2D().rotate_deg(90) + ax.transData

for x in ax.images + ax.lines + ax.collections:
    x.set_transform(r)

old = ax.axis()
ax.axis(old[2:4] + old[0:2])
这个几乎做到了这一点(请注意,过去沿白线分布的散乱点是如何放大的,并且没有按预期旋转的)。 不幸的是,保存分散结果的
PathCollection
没有按预期工作。在尝试了一些东西之后,我发现散射具有某种偏移变换,这似乎与其他集合中的常规变换等效

x = numpy.arange(5)
ax = pyplot.gca()
p0, = ax.plot(x)
p1 = ax.scatter(x,x)

ax.transData == p0.get_transform()           # True
ax.transData == p1.get_offset_transform()    # True
看起来我可能想更改散点图的偏移变换,但我没有找到任何方法允许我在
路径集合
上更改该变换。而且,这会让我做我真正想做的事情更加不方便

有人知道是否存在更改偏移变换的可能性吗


提前感谢

不幸的是,
路径集合
没有
.set\u offset\u transform()
方法,但是可以访问private
\u transOffset
属性并对其设置旋转变换

import matplotlib.pyplot as plt
from matplotlib.transforms import Affine2D
from matplotlib.collections import PathCollection
import numpy as np; np.random.seed(3)

def vis_mv(data, ax = None):
    if ax is None: ax = plt.gca()
    cmap = plt.get_cmap()
    colors = cmap(np.linspace(0, 1, len(data)))

    xs = np.arange(len(data)) + 1
    means = np.array([ np.mean(x) for x in data ])
    varis = np.array([ np.var(x) for x in data ])
    vlim = max(1, np.amax(varis))

    # variance
    ax.imshow([[0.,1.],[0.,1.]],
        cmap = cmap, interpolation = 'bicubic',
        extent = (1, len(data), -vlim, vlim), aspect = 'auto'  )
    ax.fill_between(xs, -vlim, -varis, color = 'white')
    ax.fill_between(xs, varis, vlim, color = 'white')

    # mean
    ax.plot(xs, means, color = 'white', zorder = 1)
    ax.scatter(xs, means, color = colors, edgecolor = 'white', zorder = 2)

    return ax

data = np.random.normal(size=(9, 9))
ax  = vis_mv(data)


r = Affine2D().rotate_deg(90)

for x in ax.images + ax.lines + ax.collections:
    trans = x.get_transform()
    x.set_transform(r+trans)
    if isinstance(x, PathCollection):
        transoff = x.get_offset_transform()
        x._transOffset = r+transoff

old = ax.axis()
ax.axis(old[2:4] + old[0:2])


plt.show()

你能发布你所拥有的和(大致)你想要的东西的样本图像吗?@VBB现在更清楚了吗?从垂直绘制开始怎么样
imshow
scatter
plot
将按原样工作,您可以使用
ax.fill\u betweenx
进行着色。(附言:很好的着色技巧)@VBB我最初做的每件事都是垂直的(除了我不知道ax.fill\u betweenx),但为了更仔细地观察,我把代码改写成水平的,希望我能够旋转整个东西。我显然可以有两个函数,但我希望有一个更优雅的解决方案…@ImportanceOfBeingErnest我更新了我的问题,1)提到了另一个问题的存在2)关注散点图