Как сделать relim () и autoscale () в диаграмме рассеяния

Вы можете создать Семафор и прекратить выполнение (поместите код в ваш файл * .dpr) и принесите запущенное приложение на экран.

var
  Semafor: THandle;

begin
  { Don't start twice ... if already running bring this instance to front }
  Semafor := CreateSemaphore(nil, 0, 1, 'MY_APPLICATION_IS_RUNNING');
  if ((Semafor <> 0) and { application is already running }
     (GetLastError = ERROR_ALREADY_EXISTS)) then 
  begin
    RestoreWindow('TMyApplication');
    CloseHandle(Semafor);
    Halt;
  end;

  Application.CreateForm(....);    
  Application.Initialize;
  Application.Run;
  CloseHandle(Semafor);
end;

EDIT (добавлен метод RestoreWindow). :

aFormName - это имя вашего основного класса формы в вашем приложении.

procedure RestoreWindow(aFormName: string);
var
  Wnd,
  App: HWND;    
begin
  Wnd := FindWindow(PChar(aFormName), nil);
  if (Wnd <> 0) then 
  begin { Set Window to foreground }
    App := GetWindowLong(Wnd, GWL_HWNDPARENT);
    if IsIconic(App) then 
      ShowWindow(App, SW_RESTORE);

    SetForegroundwindow(App);
  end;
end;
1
задан user1993416 13 July 2018 в 10:54
поделиться

2 ответа

Оба .relim() и .autoscale_view() не вступают в силу, когда границы осей ранее были установлены через .set_ylim(). Поэтому .set_ylim() необходимо удалить из кода.

Кроме того, обновление границ графика рассеяния (которое является matplotlib.collections.PathCollection) немного сложнее, чем для других графиков.

Сначала вам нужно обновить datalimits осей перед вызовом autoscale_view(), потому что .relim() не работает с коллекциями.

ax.ignore_existing_data_limits = True
ax.update_datalim(scatter.get_datalim(ax.transData))
ax.autoscale_view()

Вот минимальный воспроизводимый пример:

from ipywidgets import widgets
from IPython.display import display
import matplotlib.pyplot as plt
import numpy as np
%matplotlib notebook

x = np.arange(10)

fig, ax = plt.subplots()
scatter = ax.scatter(x,x, label="y = a*x+b")

ax.legend()

def update_plot(a, b):
    y = a*x+b
    scatter.set_offsets(np.c_[x,y])

    ax.ignore_existing_data_limits = True
    ax.update_datalim(scatter.get_datalim(ax.transData))
    ax.autoscale_view()

    fig.canvas.draw_idle()

a = widgets.FloatSlider(min=0.5, max=4, value=1, description= 'a:')
b = widgets.FloatSlider(min=0, max=40, value=10, description= 'b:')
widgets.interactive(update_plot, a=a, b=b)
2
ответ дан ImportanceOfBeingErnest 17 August 2018 в 13:06
поделиться
  • 1
    Спасибо. Решение работает отлично, и проблема была действительно трудной для меня. – user1993416 13 July 2018 в 15:26

Поскольку , записанный в документации для Axes.relim() , Collections (который является типом, возвращаемым scatter()), в данный момент не поддерживается.

Поэтому вы нужно вручную ограничить пределы, что-то вроде

(...)
line3.set_offsets(np.c_[rd,prob_error])
ax3.set_xlim((min(rd),max(rd)))
ax3.set_ylim((min(prob_error),max(prob_error)))

Мне кажется, что все ваши сюжеты имеют одинаковые значения x, правда? Если это так, вы можете использовать fig, (ax1, ax2,ax3) = plt.subplots((...), sharex=True). Вам все равно придется установить ylim для ax3 вручную, но по крайней мере ваши x-оси будут одинаковыми во всех подсети.

EDIT: Теперь я понимаю, что это выглядит как ваши данные в ax3 связаны между [0-1] и что вам, вероятно, не нужно изменять ylim (), и что совместного использования оси x с другими подзарядами должно быть достаточно.

0
ответ дан Diziet Asahi 17 August 2018 в 13:06
поделиться
Другие вопросы по тегам:

Похожие вопросы: