Embedding small plots inside subplots in matplotlib
I wrote a function very similar to plt.axes. You could use it for plotting yours sub-subplots. There is an example...
import matplotlib.pyplot as plt
import numpy as np
#def add_subplot_axes(ax,rect,facecolor='w'): # matplotlib 2.0+
def add_subplot_axes(ax,rect,axisbg='w'):
fig = plt.gcf()
box = ax.get_position()
width = box.width
height = box.height
inax_position = ax.transAxes.transform(rect[0:2])
transFigure = fig.transFigure.inverted()
infig_position = transFigure.transform(inax_position)
x = infig_position[0]
y = infig_position[1]
width *= rect[2]
height *= rect[3] # <= Typo was here
#subax = fig.add_axes([x,y,width,height],facecolor=facecolor) # matplotlib 2.0+
subax = fig.add_axes([x,y,width,height],axisbg=axisbg)
x_labelsize = subax.get_xticklabels()[0].get_size()
y_labelsize = subax.get_yticklabels()[0].get_size()
x_labelsize *= rect[2]**0.5
y_labelsize *= rect[3]**0.5
subax.xaxis.set_tick_params(labelsize=x_labelsize)
subax.yaxis.set_tick_params(labelsize=y_labelsize)
return subax
def example1():
fig = plt.figure(figsize=(10,10))
ax = fig.add_subplot(111)
rect = [0.2,0.2,0.7,0.7]
ax1 = add_subplot_axes(ax,rect)
ax2 = add_subplot_axes(ax1,rect)
ax3 = add_subplot_axes(ax2,rect)
plt.show()
def example2():
fig = plt.figure(figsize=(10,10))
axes = []
subpos = [0.2,0.6,0.3,0.3]
x = np.linspace(-np.pi,np.pi)
for i in range(4):
axes.append(fig.add_subplot(2,2,i))
for axis in axes:
axis.set_xlim(-np.pi,np.pi)
axis.set_ylim(-1,3)
axis.plot(x,np.sin(x))
subax1 = add_subplot_axes(axis,subpos)
subax2 = add_subplot_axes(subax1,subpos)
subax1.plot(x,np.sin(x))
subax2.plot(x,np.sin(x))
if __name__ == '__main__':
example2()
plt.show()
Plot inside a plot
OK, here's an example, which I plotted to a 10 by 10 inch pdf. (Part of what's frustrating about using par(fig = )
et al. is that their effects are very much dependent on the size of the plotting device.)
Edited to add some explanation:
The base graphic plotting parameter par("fig")
describes/sets the location of a figure region as a proportion of the "drawing region" (which is usually the entire device, for single figure plots). It takes a length-4 vector of the form c(xmin, xmax, ymin, ymax)
consisting of numbers (proportions) between 0
and 1
.
Here I use grconvertX()
and grconvertY()
to convert x-y locations expressed in terms of the larger plot's own (a.k.a. "user"
) coordinate system into the "ndc"
(normalized device coordinates) coordinate system. The "user"
coordinate system is more human-user-friendly, while the "ndc"
is (with the caveats expressed above) the coordinate system used by par("fig")
. The grconvert*()
calls are just there to perform the translation between them.
## pdf("fig-in-fig.pdf", width=10, height=10)
curve(exp(x), from=1, to=5, lwd=5)
curve(150-exp(x), from=1, to=5, lwd=5, col="darkblue",add=T)
## Here's the bit I added.
par(fig = c(grconvertX(c(1, 3), from="user", to="ndc"),
grconvertY(c(50, 125), from="user", to="ndc")),
mar = c(4,6,1,1),
new = TRUE)
curve(exp(x), from=1, to=5, lwd=7, xlab="chi", ylab="exp(x)", cex.lab=4,axes=F)
axis(1, labels=NA,at=c(0,5))
axis(2, labels=NA,at=c(0,150))
text(1,120,"Alpha",adj=c(0,0),cex=3)
text(3.5,10,"Beta",adj=c(0,0),cex=3)
## dev.off()
Gnuplot: multiplot and insets
This is how I understand your question. I guess you simply need to set the origin and sizes yourself. You can use variables to calculate the necessary values.
Code:
### multiplot with "insets"
reset session
set key top left
set multiplot
# settings for main plots
set ytics auto
# first plot
s1x = 0.5
s1y = 1.0
set size s1x, s1y
o1x = 0.0
o1y = 0.0
set origin o1x, o1y
plot exp(-x)
# second plot
s2x = 0.5
s2y = 1.0
set size s2x, s2y
o2x = 0.5
o2y = 0.0
set origin o2x, o2y
set ytics auto
plot exp(-2*x)
# settings for insets
set ytics 0.5
# first inset
set size s1x*0.6, s1y*0.5
set origin o1x+s1x*0.4, o1y+s1y*0.5
plot cos(x)
# second inset
set size s2x*0.6, s2y*0.5
set origin o2x+s2x*0.4, o2y+s2y*0.5
plot sin(x)
unset multiplot
### end of code
Result:
How to add different graphs (as an inset) in another python graph
There's more than one way do to this, depending on the relationship that you want the inset to have.
If you just want to inset a graph that has no set relationship with the bigger graph, just do something like:
import matplotlib.pyplot as plt
fig, ax1 = plt.subplots()
# These are in unitless percentages of the figure size. (0,0 is bottom left)
left, bottom, width, height = [0.25, 0.6, 0.2, 0.2]
ax2 = fig.add_axes([left, bottom, width, height])
ax1.plot(range(10), color='red')
ax2.plot(range(6)[::-1], color='green')
plt.show()
If you want to have some sort of relationship between the two, have a look at some of the examples here: http://matplotlib.org/1.3.1/mpl_toolkits/axes_grid/users/overview.html#insetlocator
This is useful if you want the inset to be a "zoomed in" version, (say, at exactly twice the scale of the original) that will automatically update as you pan/zoom interactively.
For simple insets, though, just create a new axes as I showed in the example above.
How to place a matplotlib plot inside a tkinter window in the simplest way possible?
Try this:
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
import tkinter as tk
# All of your code
root = tk.Tk() # Create the tkinter window
canvas = FigureCanvasTkAgg(fig, master=root) # Convert the Figure to a tkinter widget
canvas.get_tk_widget().pack() # Show the widget on the screen
canvas.draw() # Draw the graph on the canvas?
root.mainloop() # Start tkinter's mainloop
That will show your Figure
on the screen. Please note that it uses the fig
that you defined when you used fig, ax = plt.subplots()
Related Topics
Remove 'Search' Option But Leave 'Search Columns' Option
Subset Rows According to a Range of Time
Dual Y Axis in Ggplot2 for Multiple Panel Figure
Index Unique Values in Data.Table
Calculating Peaks in Histograms or Density Functions
Ggpairs Plot with Heatmap of Correlation Values
R Remove Last Word from String
Is There a Fast Estimation of Simple Regression (A Regression Line with Only Intercept and Slope)
Finding Overlapping Ranges Between Two Interval Data
How to Expand Axis Asymmetrically with Ggplot2 Without Setting Limits Manually
Stop Lapply from Printing to Console
The Perils of Aligning Plots in Ggplot
Format Text Inside R Code Chunk
How to Add a Condition to the Geom_Point Size
How to Access Dimensions of Labels Plotted by 'Geom_Text' in 'Ggplot2'
Obtaining Connected Components of Neighboring Values
Automated Httr Authentication with Twitter , Provide Response to Interactive Prompt in "Batch" Mode