pythonmatplotlibrotationsubplot

How to superimpose the rotated subplot on the another sublot?


I would like to release such configuration of plots as it presented on the picture: enter image description here

The next parameters have to be variable:

  1. Position of subplot origin point
  2. Rotation angle of subplot
  3. Size of subplot

I tried to find solution using mpl_toolkits.axes_grid1.inset_locator.inset_axes (see below), but I can't change values of parameters 1,2 from the list above. Please, help me to find solution.

import matplotlib.pyplot as plt
import numpy as np
from mpl_toolkits.axes_grid1.inset_locator import inset_axes

x = np.linspace(0,100,100)
y = np.linspace(0,100,100)

fig, ax = plt.subplots(1, 1, figsize=[8, 8])
axins = inset_axes(ax, width='40%', height='40%', loc='center')
axins.set_xlim(0,80)
axins.set_ylim(0,80)
axins.plot(x,y)

plt.show()

enter image description here


Solution

  • Based on using a floating axis (as in this answer) and the example here, I have the following solution:

    import numpy as np
    
    import matplotlib.pyplot as plt
    from matplotlib.transforms import Affine2D
    import mpl_toolkits.axisartist.floating_axes as floating_axes
    from mpl_toolkits.axisartist.grid_finder import MaxNLocator
    
    # create a figure and original axis
    fig, ax_orig = plt.subplots(figsize=(7, 7))
    
    # data for plotting in subplot
    subplot_xdata = np.linspace(0, 80, 100)
    subplot_ydata = np.linspace(0, 80, 100)
    
    # extents of the subplot (based on data)
    plot_extents = (
        subplot_xdata[0],
        subplot_xdata[-1],
        subplot_ydata[0],
        subplot_ydata[-1],
    )
    
    # create the floating subplot
    rotation = 145  # rotation of subplot (degrees)
    transform = Affine2D().rotate_deg(rotation)  # transform with rotation applied
    
    # set the subplot grid to allow ticks at multiples of 5 or 10
    grid_locator = MaxNLocator(steps=[5, 10])
    
    helper = floating_axes.GridHelperCurveLinear(
        transform,
        plot_extents,
        grid_locator1=grid_locator,
        grid_locator2=grid_locator,
    )
    ax = floating_axes.FloatingSubplot(fig, 111, grid_helper=helper)
    
    # position and scale the subplot (play about with these)
    width = 0.35  # width relative to original axis
    height = 0.35  # height relative to original axis
    xloc = 0.4  # x-location (in axis coordinates between 0-1) of bottom left corner of (unrotated) subplot
    yloc = 0.5  # y-location of bottom left corner of (unrotated) subplot
    ax.set_position((xloc, yloc, width, height))
    
    # get auxilary axis to for actually plotting the subplot data
    aux_ax = ax.get_aux_axes(transform)
    aux_ax.plot(subplot_xdata, subplot_ydata)
    
    # add subplot to the figure
    fig.add_subplot(ax)
    
    # plot something on the original axes
    ax_orig.plot(np.linspace(0, 2, 100), np.linspace(0, 2, 100))
    

    enter image description here

    Note that this solution requires you to specify the x-y extent of your subplot.