鼠标单击事件带有子图数据的新图形

时间:2018-10-08 11:11:06

标签: python matplotlib mouseclick-event

我在一个图形中有几个子图,我想创建一个鼠标事件(双击),这样,当单击一个子图时,只用该图打开一个新图,即一种缩放

enter image description here

我将您的解决方案合并到了我的代码中。.鼠标事件尚不起作用。 可能与我递归创建轴的事实有关吗?

def plot_time_traces(diag_json,pulselist,save=False):
"""
this routines plots time traces of JET diagnostics

uses as input JSON file that contains info on the diagnostic the user wants
to plot and info on how to plot them (i.e. what window, linestyle, marker...)



:param diag_json: standard set containing the diagnostic the user wants to plot
:param pulselist: list of pulses (and colors)
:return:
"""
logging.info('using standard set {}'.format(diag_json))

logging.info('pulselist {}'.format(pulselist))


default = True
fold = './standard_set/'
with open(fold+diag_json, mode='r', encoding='utf-8') as f:
    # Remove comments from input json
    with open(fold+"temp.json", 'w') as wf:
        for line in f.readlines():
            if line[0:2] == '//' or line[0:1] == '#':
                continue
            wf.write(line)

with open(fold+"temp.json", 'r') as f:
    input_dict = json.load(f, object_pairs_hook=OrderedDict)
    os.remove(fold+'temp.json')

try:
    ppflen = (len(input_dict['ppf']))
except:
    ppflen = 0
try:
    jpflen = (len(input_dict['jpf']))
except:
    jpflen = 0
totsignal = (ppflen + jpflen)
logging.info('reading {} signals'.format(str(totsignal)))
try:
    iColumn = int(input_dict['icolumn'])
    iRow = int(input_dict['irow'])
    linewidth = float(input_dict['linewidth'])
    markersize = float(input_dict['markersize'])
    default = False
except:
    iColumn = 4
    iRow = int(round(totsignal / iColumn))
    linewidth = 0.5
    markersize =  1

logging.debug('subplot {} x {}'.format(str(iRow),str(iColumn)))




units = []
names = []
dataname = []
pulse_list = []
time = strftime("%Y-%m-%d %H:%M:%S", gmtime())
path = '/u/bviola/work/Python/EDGE2D/exp_data'
fig = plt.figure()


fig.set_size_inches(18.5, 10.5)
t = Toggle()
fig.canvas.mpl_connect("button_press_event", t.toggle)
for index,element in enumerate(pulselist):


    pulse = int(pulselist[index][0])
    pulse_list.append(pulse)

    logging.info('\n')
    logging.info('reading data for pulse %s ', pulse)

    indexSubPlot = 0

    for key, value in input_dict.items():
        for value in input_dict[key]:


            system=key
            node=value
            # print(value)



            if system == 'ppf':
                user=node.split('/')[0]
                ppfuid(user, "r")
                dda=node.split('/')[1]
                dtype=node.split('/')[2]

                # logging.debug('reading data %s ', key + '_' + dda + '_' + dtype)

                data_name = 'data_' + key + '_' + dda + '_' + dtype
                time_name = 't_data_' + key + '_' + dda + '_' + dtype
                unit_name = 'units_' + '_' + dda + '_' + dtype

                vars()[data_name], x, vars()[time_name], nd, nx, nt, vars()[
                    unit_name], xunits, tunits, desc, comm, seq, ier = \
                    ppfdata(pulse, dda, dtype, seq=0, uid=user,
                            device="JET", fix0=0, reshape=0, no_x=0, no_t=0)
                if ier == 0 :
                    logging.info('read data %s ', key + '_' + dda + '_' + dtype + 'seq {}'.format(str(seq)))
                else:
                    logging.info('no data')


                if default == True:
                    indexSubPlot = indexSubPlot + 1
                    ax_name = 'ax_' + str(indexSubPlot)
                    marker = 'x'
                    linestyle = ':'
                    logging.debug('using default options for ppf')

                else:
                    indexSubPlot = int(input_dict[system][value][0])
                    ax_name = 'ax_' + str(input_dict[system][value][0])
                    marker = input_dict[system][value][1]
                    linestyle = input_dict[system][value][2]
                    logging.debug('using JSON options for ppf')


                # vars()[indexSubPlot] = fig.add_subplot(iRow, iColumn, indexSubPlot)
                if indexSubPlot == 1:
                    ax_1 = plt.subplot(iRow, iColumn, indexSubPlot)
                else:
                    vars()[ax_name] = plt.subplot(iRow, iColumn,indexSubPlot,sharex=ax_1)

                plt.plot(vars()[time_name], vars()[data_name],
                             label=str(pulse) + ' ' + node, marker = marker, linestyle=linestyle, linewidth=linewidth,
                         markersize=markersize)
                plt.legend(loc='best', prop={'size': 6})
                plt.xlabel('time[s]')
                plt.ylabel(vars()[
                    unit_name])
                # plt.hold(True)

            if system == 'jpf':
                data_name = 'data_' + key + '_' + value
                time_name = 't_data_' + key + '_' + value
                unit_name = 'units_' + key + '_' + value



                vars()[data_name], vars()[time_name], IplSigLen, IplSigTitle, vars()[
                    unit_name], ier = getdat.getdat(value,pulse)
                if ier == 0 :
                    logging.info('read data  ' + key + '_' + value )
                else:
                    logging.info('no data')





                if default == True:
                    indexSubPlot = indexSubPlot + 1
                    ax_name = 'ax_' + str(indexSubPlot)
                    marker = 'x'
                    linestyle = ':'
                    logging.debug('using default options for ppf')

                else:
                    indexSubPlot = int(input_dict[system][value][0])
                    ax_name = 'ax_' + str(input_dict[system][value][0])
                    marker = input_dict[system][value][1]
                    linestyle = input_dict[system][value][2]
                    logging.debug('used JSON options for jpf')




                if indexSubPlot == 1:
                    ax_1 = plt.subplot(iRow, iColumn,indexSubPlot)

                else:
                    vars()[ax_name] = plt.subplot(iRow, iColumn,
                                                       indexSubPlot,sharex=ax_1)
                plt.plot(vars()[time_name], vars()[data_name],
                             label=str(pulse) + ' ' + value, marker = marker, linestyle=linestyle, linewidth=linewidth,
                         markersize=markersize)

                plt.legend(loc='best', prop={'size': 6})
                # plt.ylabel(IplSigTitle)
                plt.ylabel(vars()[
                               unit_name])
                plt.xlabel('time[s]')



logging.info('plot DONE')
gs = GridSpec(1, 1)

# fig.tight_layout()
if save is True:
    cwd = os.getcwd()

    pulses = "-".join(str(n) for n in pulse_list)

    fname = diag_json[:-5]+'_'+pulses

    plt.savefig('figures/' + fname+'.png', format='png', dpi=300)

    logging.info('picture saved to {}'.format(cwd+os.sep+'figures/'+fname))

1 个答案:

答案 0 :(得分:1)

matplotlib event handling tutorial对事件进行了很好的介绍。在这里,我看到两个选项:

点击创建新图形

您可以在button_press_event的回调中创建图形。根据单击的轴,可以在新图形中重新创建相同的图。

import matplotlib.pyplot as plt
import numpy as np


def create_plot(num, ax=None):
    ax = ax or plt.gca()
    t = np.linspace(0,2*np.pi,101)
    ax.plot(t, np.sin(num*t), label="Label {}".format(num))
    ax.legend()

fig, axes = plt.subplots(5,4)

for i,ax in enumerate(axes.flat):
    create_plot(i, ax=ax)


def create_fig(evt):
    if evt.inaxes:
        newfig, newax = plt.subplots()
        num = fig.axes.index(evt.inaxes)
        create_plot(num, ax=newax)
        newfig.show()

fig.canvas.mpl_connect("button_press_event", create_fig)

plt.show()  

在图中放大。

您可以在同一图中执行所有操作。这个想法是,一旦发生单击,将除单击的轴之外的所有轴都设置为不可见,并使单击的轴填充整个子图网格的空间。再次单击单个轴,再次使所有轴可见,并将轴放回其原始位置。优点是您无需重新创建任何图。

import matplotlib.pyplot as plt
import numpy as np
from matplotlib.gridspec import GridSpec


fig, axes = plt.subplots(5,4)

for i,ax in enumerate(axes.flat):
    ax.plot(np.arange(20), np.cumsum(np.random.randn(20)), label="Label {}".format(i))
    ax.legend()

gs = GridSpec(1,1)

class Toggle():
    def __init__(self):
        self.all_visible = True
        self.opos = None

    def toggle(self,evt):
        if evt.inaxes:
            if self.all_visible:
                for ax in fig.axes:
                    if ax != evt.inaxes:
                        ax.set_visible(False)
                self.opos = evt.inaxes.get_position()
                evt.inaxes.set_position(gs[0].get_position(fig))
                self.all_visible=False
            else:
                for ax in fig.axes:
                    ax.set_visible(True)

                evt.inaxes.set_position(self.opos)
                self.all_visible = True
                self.opos = None
            fig.canvas.draw_idle()

t = Toggle()
fig.canvas.mpl_connect("button_press_event", t.toggle)

plt.show()