Что я хочу сделать, так это повернуть и перевернуть метки осей на графике 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()
Это участки:
Однако я хочу получить вот это (картинка редактировалась вручную в Gimp):
Вращение уже обсуждалось, например, в Повернуть текст оси в python matplotlib - но возможно ли сделать инвертирование/ флип, и если да, то как (и сохранится ли поворот+флип при масштабировании)?
1 ответ
Я опубликую это как ответ: нашел, как это сделать (необходимо использовать эффекты пути и преобразования) - однако:
- Метки после преобразования не совсем совпадают с отметками осей.
- Преобразование сохраняется для увеличения, но печатаются неправильные метки (т. е. тот же набор меток [скажем, от 0 до 100] появляется после увеличения, которое в противном случае должно отображать только подмножество [скажем, от 20 до 40])
Если кто-нибудь может помочь с этим (особенно если нет «ручной настройки»), я приму этот ответ.
В противном случае приведенный ниже код выдает:
... и код:
#!/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()
Похожие вопросы
Связанные вопросы
Новые вопросы
matplotlib
Matplotlib - это библиотека черчения для Python, которую можно использовать в интерактивном режиме или встраивать в автономные графические интерфейсы. Его компактный интерфейс «pyplot» аналогичен функциям построения графиков MATLAB®.