在matplotlib中翻转/反转轴标签?

时间:2019-11-29 10:39:11

标签: matplotlib

我想做的是在matplotlib图上同时旋转和翻转轴标签-考虑以下示例:

#!/usr/bin/python3
# -*- coding: utf-8 -*-

import matplotlib
import matplotlib.pyplot as plt

default_size_inch = (9, 6)

x1 = [0,1] ; y1 = [0,100]

fig = plt.figure(figsize=default_size_inch, dpi=120)
ax1 = fig.add_subplot()

ax1.plot(x1, y1, color="Red")
ax1.set(xlabel='X label', ylabel='Y label')

plt.show()

此图:

figure1

但是,我想得到的是这张照片(图片是在Gimp中手动编辑的):

figure2

旋转已经在例如Rotate axis text in python matplotlib-但是可以进行反转/翻转,如果可以的话,如何进行缩放(缩放时是否保留旋转+翻转)?

1 个答案:

答案 0 :(得分:0)

我将其发布为答案:找到了如何做到这一点(需要使用路径效果和变换)-但是:

  • 标签一旦转换,就无法与轴的刻度线对齐
  • 该变换会持续进行缩放-但是会打印错误的标签(即,放大后会出现同一组标签[例如0到100],否则应该只显示一个子集[例如20到40])

如果任何人都可以提供帮助(特别是没有“手动调优”的情况),我将接受该答案。

否则,下面的代码将产生:

figure

...,代码为:

#!/usr/bin/python3
# -*- coding: utf-8 -*-

import matplotlib
import matplotlib.pyplot as plt
import matplotlib.patheffects as path_effects # http://coderzcolumn.com/tutorials/data-science/matplotlib-path-effect
import matplotlib.transforms as transforms # https://matplotlib.org/3.1.1/tutorials/advanced/transforms_tutorial.html


class Scale(matplotlib.patheffects.RendererBase):
  def __init__(self, sx, sy=None):
    self._sx = sx
    self._sy = sy

  def draw_path(self, renderer, gc, tpath, affine, rgbFace):
    affine = affine.identity().scale(self._sx, self._sy)+affine
    renderer.draw_path(gc, tpath, affine, rgbFace)


default_size_inch = (9, 6)

x1 = [0,1] ; y1 = [0,100]

fig = plt.figure(figsize=default_size_inch, dpi=120)
ax1 = fig.add_subplot()

ax1.plot(x1, y1, color="Red")
ax1.set(xlabel='X label', ylabel='Y label')

fig.canvas.draw() # must have (and not draw_idle), else no get_xticklabels
#print(ax1.get_xticklabels()[0].get_transform())
ax1.set_xticklabels(
  ax1.get_xticklabels(),
  rotation=-90, rotation_mode='default', ha='right',
  #path_effects=[path_effects.withSimplePatchShadow(), path_effects.Normal()],
  #transform=transforms.Affine2D(), # each label has individual transform (?), try a loop instead (see also https://stackoverflow.com/questions/52491287/matplotlib-pyplot-has-partial-xtick-labels-that-dont-rotate)
)

xlaboffset = matplotlib.transforms.ScaledTranslation(0.05, -0.25, fig.dpi_scale_trans) # manually tuned
# even if applied individually, (label.get_transform() + transforms.Affine2D().clear().rotate_deg(5)) actually results with labels being rotated as if on a line
for label in ax1.get_xticklabels():
  label.set_path_effects([Scale(-1.0, 1.0)]) # mirror/flip
  label.set_transform(label.get_transform() + xlaboffset) # https://stackoverflow.com/questions/28615887/how-to-move-a-ticks-label-in-matplotlib

ax1.set_yticklabels(
  ax1.get_yticklabels(),
  rotation=-90,
)
ylaboffset = matplotlib.transforms.ScaledTranslation(0.00, -0.25, fig.dpi_scale_trans)
for label in ax1.get_yticklabels():
  label.set_path_effects([Scale(-1.0, 1.0)]) # mirror/flip
  label.set_transform(label.get_transform() + ylaboffset)


plt.show()