@mickey1129

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

python matplotlibで2軸グラフ表示時クリックした点の座標を取得できるようにしたい

解決したいこと

pythonでcsvデータをグラフ表示し、グラフ上の点をクリックした時にカーソルの座標値を取得しようとしています。csvデータにはデータAとデータBがあり、グラフ表示では横軸は共通・縦軸は別にしています。クリックで座標値取得できるようにはなったのですが、縦軸のデータがデータBの軸に合った値となっています。データAの軸に合った値を取得する方法をご教示頂けないでしょうか。
pythonを使い始めた初心者なので、その他にもコードの書き方等ご指導を頂けると幸甚です。

該当するソースコード

import tkinter as tk
import tkinter.filedialog
from tkinter import ttk
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.backend_bases import (_Mode)
from matplotlib.widgets import Cursor

def main():
    RC = ReadCSV()
    datA, datB = RC.set_data()
    
    PA = PlotAll(datA, datB)
    PUx, PUy = PA.plot()
    
    print("クリックした点の座標は、X座標:", PUx, "、 Y座標:", PUy)
    
class ReadCSV:
# 実際はCSVデータの読込み
# 検討用データを入力しておく
    def __init__(self):
        self.datA = []
        self.datB = []

    def set_data(self):
        self.datA = [(0.000, 1.000), (0.007,-0.468), (0.013,-0.438), \
            (0.020, 0.819), (0.027,-0.383), (0.033,-0.358), (0.040, 0.670), \
            (0.047,-0.314), (0.053,-0.293), (0.060, 0.549), (0.067,-0.257), \
            (0.073,-0.240), (0.080, 0.449), (0.087,-0.210), (0.093,-0.197), \
            (0.100, 0.368), (0.107,-0.172), (0.113,-0.160), (0.120, 0.301), \
            (0.127,-0.141), (0.133,-0.132), (0.140, 0.247), (0.147,-0.115), \
            (0.153,-0.108), (0.160, 0.202), (0.167,-0.094), (0.173,-0.088), \
            (0.180, 0.165), (0.187,-0.077), (0.193,-0.072), (0.200, 0.135)]
        self.datA = tuple(self.datA)
        self.datB = [(0.00,   0), (0.02,   4), (0.04,  16), (0.06,  36), \
                     (0.08,  64), (0.10, 100), (0.12, 144), (0.14, 196), \
                     (0.16, 256), (0.18, 324), (0.20, 400)]
        self.datB = tuple(self.datB)
        return self.datA, self.datB

class PlotAll:
# 全データをグラフに表示
# クリックした点の座標を取得する
    def __init__(self, dA, dB):
        self.datA    = dA
        self.datB    = dB
        self.plot_Xa = []
        self.plot_Ya = []
        self.plot_Xb = []
        self.plot_Yb = []
        
    def setData(self):
        for i in range(len(self.datA)):
            self.plot_Xa.append(self.datA[i][0])
            self.plot_Ya.append(self.datA[i][1])
        for i in range(len(self.datB)):
            self.plot_Xb.append(self.datB[i][0])
            self.plot_Yb.append(self.datB[i][1])

    def plot(self):
        self.setData()

        self.fig, self.ax_A = plt.subplots()
        self.ax_B = self.ax_A.twinx()
        self.ax_A.plot(self.plot_Xa, self.plot_Ya, color="red")
        self.ax_B.plot(self.plot_Xb, self.plot_Yb, color="blue")

        self.win = tk.Tk()
        self.win.withdraw()
        self.win.protocol('WM_DELETE_WINDOW', lambda: self.clickX(self.win))
    
        self.canvas = FigureCanvasTkAgg(self.fig, master=self.win)
        self.canvas.draw()
        self.canvas.get_tk_widget().pack()
        self.cursor = Cursor(self.ax_B, useblit=True, color="green")
        self.fig.canvas.mpl_connect("button_press_event", \
                                lambda event: self.clickSP(event, self.win))

        self.win.update()
        self.win.deiconify()
        self.win.mainloop()

        return self.PUx, self.PUy

    def clickSP(self, event, win):
        self.win = win
        x_val, y_val = (event.xdata, event.ydata)
        self.PUx = x_val
        self.PUy = y_val
        self.close_window(self.win)

    def clickX(self, win):
        self.win = win
        self.PUx = 0
        self.PUy = 0
        self.close_window(self.win)

    def close_window(self, win):
        self.win = win
        self.win.quit()
        self.win.destroy()

if __name__ == "__main__":
    main()

自分で試したこと

データBのグラフを描いた後にデータAのグラフを描けばよいのではないかと考え、.plot()の次の行に.set_zorder()を追加してみました。

    self.ax_A.set_zorder(2)
    self.ax_B.set_zorder(1)

データAの軸に合った値を取得できるようにはなったのですが、データBのグラフが消えてしまいました。

0 likes

No Answers yet.

Your answer might help someone💌