РЕДАКТИРОВАТЬ: После публикации я понял, что здесь происходит несколько вопросов, которые, вероятно, лучше решать по одному. Поэтому я собираюсь отредактировать этот пост, чтобы сосредоточиться на первой из проблем. В (обновленном / сокращенном) коде ниже я генерирую те же 3 исходных графика, используя тот же метод, что и раньше (и тот же метод для всех 3 графиков), за исключением того, что в этом случае я НЕ использовал никакого преобразования для перемещения меток тиков. , Я использовал ТОЛЬКО горизонтальное и вертикальное выравнивание меток с помощью метода ax.xaxis.get_majorticklabels(), ha='left'
(или va=
и правильное направление). На верхнем графике все выглядит нормально (все метки центрированы, кроме минимума и максимума на каждой оси), но на нижних 2 графиках все метки на положительной горизонтальной оси смещены вправо. Только последняя (максимальная) метка должна быть смещена. Удивительно, но и метка min и max вертикальной оси, и метка min горизонтальной оси смещены правильно.
Может кто-нибудь помочь мне понять, что / почему все метки на положительной горизонтальной оси сдвинуты?
import tkinter as tk
from tkinter import ttk
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
import matplotlib.pyplot as plt
import matplotlib
import matplotlib.transforms
from matplotlib.figure import Figure
matplotlib.use("TkAgg")
class MainGUI(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
self.geometry('1024x768')
self.nb = ttk.Notebook(self) # Adds tabs to main window
self.nb.grid(row=0, column=0, columnspan=50, rowspan=49, sticky='NESW')
self.tab3 = ttk.Frame(self.nb)
self.nb.add(self.tab3, text='Tab3')
self.rowconfigure(0, weight=1)
self.columnconfigure(0, weight=1)
tab3_r = 14
tab3_c = 4
for i in range(tab3_r):
self.tab3.rowconfigure(i, weight=1)
for i in range(tab3_c):
self.tab3.columnconfigure(i, weight=1)
self.delx = 5 / 72.
self.dely = 5 / 72.
self.initializeLoadPlot()
def initializeLoadPlot(self):
self.Lfig = Figure()
self.loadFig = self.Lfig.add_subplot(111, label='loadPlotMainXY')
self.stylize_plot(ax=self.loadFig, fig=self.Lfig)
self.LborderXY = self.Lfig.add_subplot(111, label='loadPlotBorderXY')
self.LborderXY.patch.set_visible(False)
self.LborderXY.tick_params(left=False, bottom=False, labelleft=False, labelbottom=False)
for _, sp in self.LborderXY.spines.items():
sp.set_linewidth(1.5)
self.loadPlotXlabXY = self.loadFig.annotate('X', xy=(1, 0), xytext=(-12.5, 12.5), ha='left', va='top', xycoords=('axes fraction', 'data'), textcoords='offset points', color='red', fontsize=12)
self.loadPlotYlabXY = self.loadFig.annotate('Y', xy=(0, 1), xytext=(5, -5), ha='left', va='top', xycoords=('data', 'axes fraction'), textcoords='offset points', color='red', fontsize=12)
self.loadPlotCGlab = self.loadFig.text(0, 0, '', fontsize=10, color='red', transform=self.loadFig.transAxes)
self.Lcanvas = FigureCanvasTkAgg(self.Lfig, self.tab3)
self.Lcanvas.draw()
self.Lcanvas.get_tk_widget().grid(column=2, row=0, columnspan=2, rowspan=5, sticky='NSEW')
self.loadBoltsXY = self.loadFig.scatter([], [], c="b", marker="o", s=40)
self.Lfig2 = Figure()
self.loadFig2 = self.Lfig2.add_subplot(121, label='loadPlotMainXZ')
self.stylize_plot(ax=self.loadFig2, fig=self.Lfig2)
self.LborderXZ = self.Lfig2.add_subplot(121, label='loadPlotBorderXZ')
self.LborderXZ.patch.set_visible(False)
self.LborderXZ.tick_params(left=False, bottom=False, labelleft=False, labelbottom=False)
for _, sp in self.LborderXZ.spines.items():
sp.set_linewidth(1.5)
self.loadPlotXlabXZ = self.loadFig2.annotate('X', xy=(1, 0), xytext=(-12.5, 12.5), ha='left', va='top', xycoords=('axes fraction', 'data'), textcoords='offset points', color='red', fontsize=12)
self.loadPlotZlabXZ = self.loadFig2.annotate('Z', xy=(0, 1), xytext=(5, -5), ha='left', va='top', xycoords=('data', 'axes fraction'), textcoords='offset points', color='red', fontsize=12)
self.loadFig3 = self.Lfig2.add_subplot(122, label='loadPlotMainYZ')
self.stylize_plot(ax=self.loadFig3, fig=self.Lfig2)
self.LborderYZ = self.Lfig2.add_subplot(122, label='loadPlotBorderYZ')
self.LborderYZ.patch.set_visible(False)
self.LborderYZ.tick_params(left=False, bottom=False, labelleft=False, labelbottom=False)
for _, sp in self.LborderYZ.spines.items():
sp.set_linewidth(1.5)
self.loadPlotXlabYZ = self.loadFig3.annotate('Y', xy=(1, 0), xytext=(-12.5, 12.5), ha='left', va='top', xycoords=('axes fraction', 'data'), textcoords='offset points', color='red', fontsize=12)
self.loadPlotYlabYZ = self.loadFig3.annotate('Z', xy=(0, 1), xytext=(5, -5), ha='left', va='top', xycoords=('data', 'axes fraction'), textcoords='offset points', color='red', fontsize=12)
self.loadBoltsXZ = self.loadFig2.scatter([], [], c="b", marker="o", s=40)
self.loadBoltsYZ = self.loadFig2.scatter([], [], c="b", marker="o", s=40)
self.Lcanvas2 = FigureCanvasTkAgg(self.Lfig2, self.tab3)
self.Lcanvas2.draw()
self.Lcanvas2.get_tk_widget().grid(column=0, row=6, columnspan=4, rowspan=5, sticky='NSEW')
def stylize_plot(self, ax=None, fig=None):
if ax is None:
ax = plt.gca()
if fig is None:
fig = plt.gcf()
ax.plot([1], [1])
ax.axis([-1, 1, -1, 1])
ax.grid(True)
fig.set_tight_layout(True)
ax.spines['left'].set_position('zero')
ax.spines['bottom'].set_position('zero')
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)
# Appears to be shifting all tick labels on positive horizontal axis for lower plots
plt.setp(ax.xaxis.get_majorticklabels()[0], ha='left')
plt.setp(ax.xaxis.get_majorticklabels()[-1], ha='right')
plt.setp(ax.yaxis.get_majorticklabels()[0], va='bottom')
plt.setp(ax.yaxis.get_majorticklabels()[-1], va='top')
ax.xaxis.set_major_formatter(matplotlib.ticker.FormatStrFormatter('%0.1f'))
ax.yaxis.set_major_formatter(matplotlib.ticker.FormatStrFormatter('%0.1f'))
if __name__ == '__main__':
MainGUI().mainloop()
Исходное сообщение:
У меня есть несколько сообщений , в которых рассматриваются способы контроля местоположения меток. Кажется, чтобы получить максимальный контроль, необходимо преобразование. Я применил это к паре цифр, и основная идея / метод работает отлично, но недавно я столкнулся с ситуацией, когда у меня возникает какое-то странное поведение, и я считаю, что это связано с преобразованием.
Когда я встраиваю 2 фигуры в окно Tkinter, одну как фигуру с 1 субплотом и одну как 1 фигуру с 2 субплотами, преобразование метки отлично работает на фигуре с одним субплотом, но на фигуре с 2 Сюжеты это не.
Основная идея состоит в том, чтобы добавить некоторые данные на график, обновить ограничения и отметки, а также переместить первый и последний отметки внутри области графика (поскольку по умолчанию они могут заканчиваться наполовину и наполовину. Это делается с помощью изменив выравнивание, а затем сместив текст немного дальше. Вы можете увидеть ожидаемый результат на верхнем графике, сгенерированном кодом ниже.
Что интересно (и моя проблема), это то, что один и тот же код не работает на нижних участках. Даже после инициализации (нет данных на графике) все положительные отметки оси X сдвигаются вправо. По какой-то причине галочки на оси Y являются желательными, как и отрицательные галочки на оси X. Когда вы добавляете данные (с помощью кнопки), он должен установить все обратно на «default» (как предложено @ImportanceOfBeingErnest, как указано в сообщении, связанном выше), а затем заново отрегулировать новые минимальные и максимальные метки тиков, но это не похоже, тоже не работает.
Итак, мой вопрос: почему это преобразование не работает на вспомогательных участках, и почему, когда я добавляю данные, оно работает нестабильно (что-то не так с тем, как я сбрасываю расположение меток перед их повторной настройкой) ?)
Заранее спасибо, как всегда.