VOOZH about

URL: https://qiita.com/kob58im/items/4ab63d0b807a07c51b98

⇱ クリックした座標近傍の複素関数の値をプロットする - Python matplotlib #数学 - Qiita


👁 Image
1

Go to list of users who liked

0

Share on X(Twitter)

Share on Facebook

Add to Hatena Bookmark

More than 3 years have passed since last update.

@kob58im

クリックした座標近傍の複素関数の値をプロットする - Python matplotlib

1
Last updated at Posted at 2023-02-01

の続き

キャプチャ

👁 image.png

操作方法

  • 画面左端のグラフ上で座標を左クリックで選択
  • 右クリックまたはウィンドウを閉じる操作で終了
  • 無操作タイムアウトでの終了は86400秒(丸一日)

左端のグラフから順に

  • $s$
  • $\xi(s) =\pi^{-\frac{s}{2}}\Gamma\left(\frac{s}{2}\right)\zeta(s)$
  • $|\xi(s))|$ (横軸は$Im(s)$)
  • $|\xi(s))|$ (横軸は$Re(s)$)

ソースコード

import matplotlib.pyplot as plt
from matplotlib import _pylab_helpers
# import cmath
import numpy as np
import mpmath
mpmath.mp.dps = 12

def zeta_relist_im_abs(re_list,im):
 z_re = np.zeros(len(re_list))
 z_im = np.zeros(len(re_list))
 z_abs = np.zeros(len(re_list))
 for i in range(len(re_list)):
 s = re_list[i] + im*1j
 tmp = mpmath.zeta(s)*mpmath.gamma(0.5*s)*mpmath.power(mpmath.pi,-0.5*s)
 z_re[i] = tmp.real
 z_im[i] = tmp.imag
 z_abs[i] = abs(tmp)
 # z_arg[i] = cmath.phase(tmp)
 return z_re,z_im,z_abs

def zeta_re_imlist_abs(re,im_list):
 z_re = np.zeros(len(im_list))
 z_im = np.zeros(len(im_list))
 z_abs = np.zeros(len(im_list))
 for i in range(len(im_list)):
 s = re + im_list[i]*1j
 tmp = mpmath.zeta(s)*mpmath.gamma(0.5*s)*mpmath.power(mpmath.pi,-0.5*s)
 z_re[i] = tmp.real
 z_im[i] = tmp.imag
 z_abs[i] = abs(tmp)
 # z_arg[i] = cmath.phase(tmp)
 return z_re,z_im,z_abs


def main():
 RE_N=11
 IM_N=51
 # RE_AMP=0.1
 IM_AMP=1
 
 fig,axes = plt.subplots(1, 4, figsize=(13,5), gridspec_kw= {'width_ratios': [1, 3, 2, 2]})
 axes[0].set_xticks([0.5,0.75,1])
 axes[0].set_xlim((0.5,1))
 axes[0].set_yticks([0,14,14.5,20])
 axes[0].set_ylim((0,20))
 axes[0].grid()
 axes[1].grid()
 axes[2].grid()
 axes[3].grid()

 # ハンドル取得のため一度plot
 lines00, = axes[0].plot([0,1], [0,0],"r") # s Re part sweep
 lines01, = axes[0].plot([0,1], [0,0],"b") # s Im part sweep s_re
 lines03, = axes[0].plot([0,1], [0,0],"g") # s Im part sweep s_re max
 lines10, = axes[1].plot([0,1], [0,0],"r") # zeta_xi(s) Re part sweep
 lines11, = axes[1].plot([0,1], [0,0],"b") # zeta_xi(s) Im part sweep
 lines13, = axes[1].plot([0,1], [0,0],"g") # zeta_xi(s) Im part sweep s_re max
 lines21, = axes[2].plot([0,1], [0,0],"b") # abs(zeta(s)) Im part sweep
 lines23, = axes[2].plot([0,1], [0,0],"g") # abs(zeta(s)) Im part sweep s_re max
 # lines24, = axes[2].plot([0,1], [0,0],"y") # diff of abs(zeta(s))
 lines3, = axes[3].plot([0,1], [0,0],"r") # abs(zeta(s)) Re part sweep 

 while True:
 manager = _pylab_helpers.Gcf.get_active()
 if manager is None:
 print('closed')
 break

 points = plt.ginput(n=1, timeout=86400, mouse_add=1, mouse_pop=2, mouse_stop=3)
 # a = plt.ginput(n=-1, mouse_add=1, mouse_pop=3, mouse_stop=2)
 # n=-1でインプットが終わるまで座標を取得
 # mouse_addで座標を取得(左クリック)
 # mouse_popでUndo(ミドルクリック)
 # mouse_stopでインプットを終了する(右クリック)

 if len(points)==1:
 re = 0.5
 re_max,im = points[0]
 print(re_max, im)
 
 re_list = np.zeros(RE_N)
 im_list_dummy = np.zeros(RE_N)

 re_list_dummy = np.zeros(IM_N)
 re_list_dummy3 = np.zeros(IM_N)
 im_list = np.zeros(IM_N)

 for i in range(RE_N):
 re_list[i] = re + (re_max-re)*i/(RE_N-1)
 im_list_dummy[i] = im

 for i in range(IM_N):
 re_list_dummy[i] = re
 re_list_dummy3[i] = re_list[-1]
 im_list[i] = im + IM_AMP*(i-(IM_N-1)/2)/((IM_N-1)/2)

 axes[0].set_ylim(None)
 lines00.set_data(re_list , im_list_dummy)
 lines01.set_data(re_list_dummy , im_list )
 lines03.set_data(re_list_dummy3, im_list )
 
 # Re sweep
 z_re1,z_im1,z_absr = zeta_relist_im_abs(re_list, im)

 # Im sweep
 z_re2,z_im2,z_abs2 = zeta_re_imlist_abs(re, im_list)
 z_re4,z_im4,z_abs4 = zeta_re_imlist_abs(re_list[-1], im_list) # [-1] means last element of the list

 lines10.set_data(z_re1, z_im1)
 lines11.set_data(z_re2, z_im2)
 lines13.set_data(z_re4, z_im4)

 # z_abs_diff = z_abs4-z_abs2
 lines21.set_data(im_list, z_abs2)
 lines23.set_data(im_list, z_abs4)
 #lines24.set_data(im_list, z_abs_diff)
 
 #tmp_abs_max1 = max(abs(z_abs_diff.min()),abs(z_abs_diff.max()))
 tmp_abs_max2 = abs(z_abs2.max())
 tmp_abs_max1 = abs(z_abs4.max())
 tmp_abs_max = max(tmp_abs_max1,tmp_abs_max2)
 #tmp_min = min(0,z_abs_diff.min())
 axes[2].set_xlim(im_list[0],im_list[-1])
 #axes[2].set_ylim(tmp_min,tmp_abs_max)
 axes[2].set_ylim(0,tmp_abs_max)

 lines3.set_data(re_list, z_absr)
 axes[3].set_xlim(re_list[0],re_list[-1])
 tmp_abs_max = abs(z_absr.max())
 tmp_abs_min = abs(z_absr.min())
 axes[3].set_ylim(tmp_abs_min,tmp_abs_max)

 tmp_abs_max1 = max(abs(z_re1.min()),abs(z_re1.max()),abs(z_re2.min()),abs(z_re2.max()),abs(z_re4.min()),abs(z_re4.max()))
 tmp_abs_max2 = max(abs(z_im1.min()),abs(z_im1.max()),abs(z_im2.min()),abs(z_im2.max()),abs(z_im4.min()),abs(z_im4.max()))
 
 axes[1].set_xlim((-tmp_abs_max1, tmp_abs_max1))
 axes[1].set_ylim((-tmp_abs_max2, tmp_abs_max2))
 #tmp_abs_max = max(tmp_abs_max1,tmp_abs_max2)
 #axes[1].set_xlim((-tmp_abs_max, tmp_abs_max))
 #axes[1].set_ylim((-tmp_abs_max, tmp_abs_max))
 else:
 print('quit by right click')
 break

 # plt.savefig('fig_test.png')
 # plt.show()
 # 次の描画(≒操作受付)までの待ち時間(秒)
 plt.pause(0.05)


if __name__ == '__main__':
 main()

参考記事

matplotlibで座標を取得

1

Go to list of users who liked

0
0

Go to list of comments

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1

Go to list of users who liked

0