在 matplotlib 中转换整个轴(或散点图) [英] transform entire axes (or scatter plot) in matplotlib

查看:60
本文介绍了在 matplotlib 中转换整个轴(或散点图)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

 将matplotlib.pyplot导入为pyplot导入 numpyvis_mv(data, ax = None):如果 ax 为 None: ax = pyplot.gca()cmap = pyplot.get_cmap()颜色 = cmap(numpy.linspace(0, 1, len(data)))xs = numpy.arange(len(data))+ 1mean = numpy.array([ numpy.mean(x) for x in data ])varis = numpy.array([数据中x的[numpy.var(x)])vlim = max(1, numpy.amax(varis))# 方差ax.imshow([[0.,1.],[0.,1.]],cmap = cmap,插值 = '双三次',范围=(1,len(数据),-vlim,vlim),方面='auto')ax.fill_between(xs, -vlim, -varis, color = 'white')ax.fill_between(xs,varis,vlim,color ='white')# 吝啬的ax.plot(xs,表示,颜色='白色',zorder = 1)ax.scatter(xs, mean, color = colors, edgecolor = 'white', zorder = 2)返回斧头

这工作得很好:但现在我希望能够以垂直方式使用这种可视化,作为某种高级颜色条,在另一个情节旁边.我希望有可能旋转整个轴及其所有内容,但我只能找到不幸的是,保存 scatter 的结果的 PathCollection 并没有达到预期的效果.经过尝试一些事情之后,我发现散点图具有某种 offset变换,这似乎与其他集合中的 regular变换等效.

x = numpy.arange(5)ax = pyplot.gca()p0, = ax.plot(x)p1 = ax.scatter(x,x)ax.transData == p0.get_transform()#正确ax.transData == p1.get_offset_transform() # 真

似乎我可能想要更改散点图的偏移变换,但我没有设法找到任何方法可以让我在 PathCollection 上更改该变换.而且,这样做会使我真正想做的事情变得更加不便.

有谁知道是否有可能改变偏移变换?

预先感谢

解决方案

不幸的是, PathCollection 没有 .set_offset_transform()方法,但是可以访问私有方法._transOffset 属性并为其设置旋转变换.

 将matplotlib.pyplot导入为plt从 matplotlib.transforms 导入 Affine2D从 matplotlib.collections 导入 PathCollection将 numpy 导入为 np;np.random.seed(3)def vis_mv(data,ax = None):如果 ax 为 None: ax = plt.gca()cmap = plt.get_cmap()颜色 = cmap(np.linspace(0, 1, len(data)))xs = np.arange(len(data)) + 1mean = 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))# 方差ax.imshow([[0.,1.],[0.,1.]],cmap = cmap,插值='bicubic',范围 = (1, len(data), -vlim, vlim), aspect = 'auto' )ax.fill_between(xs,-vlim,-varis,color ='white')ax.fill_between(xs,varis,vlim,color ='white')# 吝啬的ax.plot(xs,means, color = 'white', zorder = 1)ax.scatter(xs, mean, color = colors, edgecolor = 'white', zorder = 2)返回斧头数据 = np.random.normal(size=(9, 9))斧= vis_mv(数据)r = Affine2D().rotate_deg(90)对于 ax.images + ax.lines + ax.collections 中的 x:trans = x.get_transform()x.set_transform(r + trans)如果isinstance(x,PathCollection):transoff = x.get_offset_transform()x._transOffset = r+transoff旧 = ax.axis()ax.axis(old[2:4] + old[0:2])plt.show()

I am plotting changes in mean and variance of some data with the following code

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

This works perfectly fine: but now I would like to be able to use this visualisation also in a vertical fashion as some kind of advanced color bar kind of thingy next to another plot. I hoped it would be possible to rotate the entire axis with all of its contents, but I could only find this question, which does not really have a solid answer yet either. Therefore, I tried to do it myself as follows:

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

This almost does the trick (note how the scattered points, which used to lie along the white line, are blown up and not rotated as expected). Unfortunately the PathCollection holding the result of the scattering does not act as expected. After trying out some things, I found that scatter has some kind of offset transform, which seems to be the equivalent of the regular transform in other collections.

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

It seems like I might want to change the offset transform instead for the scatter plot, but I did not manage to find any method that allows me to change that transform on a PathCollection. Also, it would make it a lot more inconvenient to do what I actually want to do.

Would anyone know if there exists a possibility to change the offset transform?

Thanks in advance

解决方案

Unfortunately the PathCollection does not have a .set_offset_transform() method, but one can access the private _transOffset attribute and set the rotating transformation to it.

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

这篇关于在 matplotlib 中转换整个轴(或散点图)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆