Last Update: May 13, 2019
Offline Version
- Translating
- Important Note
- Basic Plot
- Plot Annotation
- Time Customization
- Subplots
- Polar Plot
- Histogram
- Bar Plot
- Error Bars
- Inexact Plot
- Pie Chart
- Scatter Plot
- Box Plot
- Major-Minor Ticks
- Mult-axis Plot
- Axis Placement
- Surface and Contour Plots
- Line Collection
- 3D Surf Plot
- Quiver Plot
- Stream Plot
- Broken Axis Subplot
Translating PyPlot code from Python to Julia can be difficult so here are a few examples comparing Python code with its Julia equivalent.
# Python
ax.set_ylim([-30, 10])
ax.spines['right'].set_color('none')
ax.spines['top'].set_color('none')
Source: Axis Boundary Color
# Julia
ax.set_ylim([-30,10])
ax.spines["top"].set_color("none") # Remove the top axis boundary
ax.spines["right"].set_color("none") # Remove the right axis boundary
The above example looked at settings of plot components. The next example will call matplotlib itself.
# Python
from matplotlib.dates import MonthLocator, WeekdayLocator, DateFormatter
majorformatter = DateFormatter("%d.%m.%Y")
minorformatter = DateFormatter("%H:%M")
majorlocator = DayLocator(interval=1)
minorlocator = HourLocator(byhour=(8,16)) # Not sure about this one
Source: Modified from this forum post by Nat Wilson and this matplotlib example.
# Julia
majorformatter = matplotlib.dates.DateFormatter("%d.%m.%Y")
minorformatter = matplotlib.dates.DateFormatter("%H:%M")
majorlocator = matplotlib.dates.DayLocator(interval=1)
minorlocator = matplotlib.dates.HourLocator(byhour=(8, 16))
# After an axis exists
ax1.xaxis.set_major_formatter(majorformatter)
ax1.xaxis.set_minor_formatter(minorformatter)
ax1.xaxis.set_major_locator(majorlocator)
ax1.xaxis.set_minor_locator(minorlocator)
The easiest way of doing a quick plot is to simply type it into the REPL (command line) but by default interactive mode might be "off". This means that when you create a figure, figure()
, nothing will appear except for the object type in the REPL, PyPlot.Figure(PyObject ...
. The command plt[:show]()
will make the figure visible but also make the REPL temporarily unusable until all figures are closed.
Changing interactive mode to "on" is as simple as running ion()
. Plots will be visible and the REPL will still be usable. It will only last for the current session though. Add it to the .juliarc.jl file to make it "on" by default. It can also be turned "off" by running ioff()
. If IJulia fails to plot inline try adding gcf()
after the plot.
Depending on the editor you are using this may be undesirable. In one mode IJulia may plot inline whereas the other may plot to a window.
Most of the basic commands in PyPlot are very similar to Matlab.
p = plot(x,y)
xlabel("X")
ylabel("Y")
PyPlot.title("Your Title Goes Here")
grid("on")
The first noticable change is in the plotting command when non-default values are used.
p = plot_date(x,y,linestyle="-",marker="None",label="Base Plot") # Basic line plot
Instead of "linestyle","-"
it uses linestyle="-"
for parameters.
The following command will point an arrow at a point and label the arrow.
annotate("Look, data!",
xy=[x;y,# Arrow tip
xytext=[x+dx;y+dy], # Text offset from tip
xycoords="data", # Coordinates in in "data" units
arrowprops=["facecolor"=>"black"]) # Julia dictionary objects are automatically converted to Python object when they pass into a PyPlot function
It's important to note that in Python the arrowprops would look like this: arrowprops=dict(arrowstyle="->")
. Dictionary definitions look like arrowprops=["facecolor"=>"black"]
in Julia.
LaTeX can be used by putting an L in front of LaTeX code, L"$\int x = \frac{x^2}{2} + C$"
.
annotate(L"$\int x = \frac{x^2}{2} + C$",
xy=[1;0],
xycoords="axes fraction",
xytext=[-10,10],
textcoords="offset points",
fontsize=30.0,
ha="right",
va="bottom")
The formatting preparation is accomplished by calling the formatters within Matplotlib.
majorformatter = matplotlib.dates.DateFormatter("%d.%m.%Y")
minorformatter = matplotlib.dates.DateFormatter("%H:%M")
majorlocator = matplotlib.dates.DayLocator(interval=1)
minorlocator = matplotlib.dates.HourLocator(byhour=(8, 16))
They are then applied to the specific axis, the handle of which is called ax1 in this case.
ax1.xaxis.set_major_formatter(majorformatter)
ax1.xaxis.set_minor_formatter(minorformatter)
ax1.xaxis.set_major_locator(majorlocator)
ax1.xaxis.set_minor_locator(minorlocator)
subplot(YXN)
, Y = number of columns, X = number of rows, N = number of axis being created
The number, N, of a grid of axes starts in the upper left (1), and goes right then down. The second axis of a 2x2 grid is the upper right axis.
subplot(313) # Create the third plot of a 3x1 group of subplots
suptitle("3x1 Subplot") # Supe title, title for all subplots combined
ax = axes(polar="true") # Create a polar axis
# Do your plotting
# Optional changes
ax.set_thetagrids(collect(0:dtheta:360-dtheta)) # Show grid lines from 0 to 360 in increments of dtheta
ax.set_theta_zero_location("N") # Set 0 degrees to the top of the plot
ax.set_theta_direction(-1) # Switch to clockwise
fig.canvas.draw() # Update the figure
h = plt.hist(x,nbins) # Histogram, PyPlot.plt required to differentiate with conflicting hist command
b = bar(x,y,color="#0f87bf",align="center",alpha=0.4)
b = barh(x,y,color="#0f87bf",align="center",alpha=0.4)
errorbar(x, # Original x data points, N values
y, # Original y data points, N values
yerr=errs, # Plus/minus error ranges, Nx2 values
fmt="o") # Format
The IJulia example does not properly apply all the formatting as the terminal version does.
xkcd() # Set to XKCD mode, based on the comic (hand drawn)
# Plot everything
p = pie(sizes,labels=labels,shadow=true,startangle=90,explode=explode,colors=colors,autopct="%1.1f%%",textprops=font)
scatter(x,y,s=areas,alpha=0.5)
boxplot(data, # Each column/cell is one box
notch=true, # Notched center
whis=0.75, # Whisker length as a percent of inner quartile range
widths=0.25, # Width of boxes
vert=false, # Horizontal boxes
sym="rs") # Symbol color and shape (rs = red square)
###########################
# Set the tick interval #
###########################
Mx = matplotlib.ticker.MultipleLocator(20) # Define interval of major ticks
f = matplotlib.ticker.FormatStrFormatter("%1.2f") # Define format of tick labels
ax.xaxis.set_major_locator(Mx) # Set interval of major ticks
ax.xaxis.set_major_formatter(f) # Set format of tick labels
mx = matplotlib.ticker.MultipleLocator(5) # Define interval of minor ticks
ax.xaxis.set_minor_locator(mx) # Set interval of minor ticks
My = matplotlib.ticker.MultipleLocator(0.5) # Define interval of major ticks
ax.yaxis.set_major_locator(My) # Set interval of major ticks
my = matplotlib.ticker.MultipleLocator(0.1) # Define interval of minor ticks
ax.yaxis.set_minor_locator(my) # Set interval of minor ticks
#########################
# Set tick dimensions #
#########################
ax.xaxis.set_tick_params(which="major",length=10,width=2,labelsize=16)
ax.xaxis.set_tick_params(which="minor",length=5,width=2)
fig.canvas.draw() # Update the figure
################
# Other Axes #
################
new_position = [0.06;0.06;0.77;0.91] # Position Method 2
ax.set_position(new_position) # Position Method 2: Change the size and position of the axis
#fig.subplots_adjust(right=0.85) # Position Method 1
ax2 = ax.twinx() # Create another axis on top of the current axis
font2 = Dict("color"=>"purple")
ylabel("Right Axis",fontdict=font2)
p = plot(x,y2,color="purple",linestyle="-",marker="o",label="Second") # Plot a basic line
ax2.set_position(new_position) # Position Method 2
setp(ax2.get_yticklabels(),color="purple") # Y Axis font formatting
ax3 = ax.twinx() # Create another axis on top of the current axis
ax3.spines["right"].set_position(("axes",1.12)) # Offset the y-axis label from the axis itself so it doesn't overlap the second axis
font3 = Dict("color"=>"green")
ylabel("Far Right Axis",fontdict=font3)
p = plot(x,y3,color="green",linestyle="-",marker="o",label="Third") # Plot a basic line
ax3.set_position(new_position) # Position Method 2
setp(ax.get_yticklabels(),color="green") # Y Axis font formatting
axis("tight")
# Enable just the right part of the frame
ax3.set_frame_on(true) # Make the entire frame visible
ax3.patch.set_visible(false) # Make the patch (background) invisible so it doesn't cover up the other axes' plots
ax3.spines["top"].set_visible(false) # Hide the top edge of the axis
ax3.spines["bottom"].set_visible(false) # Hide the bottom edge of the axis
fig.canvas.draw() # Update the figure
ax.spines["top"].set_visible(false) # Hide the top edge of the axis
ax.spines["right"].set_visible(false) # Hide the right edge of the axis
ax.spines["left"].set_position("center") # Move the right axis to the center
ax.spines["bottom"].set_position("center") # Most the bottom axis to the center
ax.xaxis.set_ticks_position("bottom") # Set the x-ticks to only the bottom
ax.yaxis.set_ticks_position("left") # Set the y-ticks to only the left
ax2.spines["top"].set_visible(false) # Hide the top edge of the axis
ax2.spines["right"].set_visible(false) # Hide the right edge of the axis
ax2.xaxis.set_ticks_position("bottom")
ax2.yaxis.set_ticks_position("left")
ax2.spines["left"].set_position(("axes",-0.03)) # Offset the left scale from the axis
ax2.spines["bottom"].set_position(("axes",-0.05)) # Offset the bottom scale from the axis
Thanks to Daniel Høegh for providing this example.
plot_surface(xgrid, ygrid, z, rstride=2,edgecolors="k", cstride=2,
cmap=ColorMap("gray"), alpha=0.8, linewidth=0.25)
contour(xgrid, ygrid, z, colors="black", linewidth=2.0)
ax.label(cp, inline=1, fontsize=10)
Thanks to David P. Sanders for this example.
# First Segment Group
xs = [1.,3.,5.,0.]
ys = [2.,4.,.06,0.]
lines = Any[collect(zip(xs,ys))]
# lines = [(1.0,2.0),(3.0,4.0),(5.0,0.06),(0.0,0.0)]
# Second Segment Group
xs = [3.,4]
ys = [5.,6]
push!(lines,collect(zip(xs,ys)))
# Third Segment Group
xs = [8.,2]
ys = [2.,4]
push!(lines,collect(zip(xs,ys)))
##############
## Colors ##
##############
# Line segments will be plotted with the following order of colors and will
# cycle back to the beginning of the array when it has gone through all of them
c = Vector{Int}[[1,0,0],[0,1,0],[0,0,1]]
# Assemble everything into a LineCollection
line_segments = matplotlib.collections.LineCollection(lines,colors=c)
############
## Plot ##
############
fig = figure("Line Collection Example",figsize=(10,10))
ax = PyPlot.axes()
ax.add_collection(line_segments)
axis("image")
Thanks to feima0011 for this example.
surf(x,y,z,facecolors=colors)
q = quiver(X,Y,U,V)
ax = gca()
ax.quiverkey(q,X=0.07,Y = 0.05, U = 10,coordinates="figure", label="Quiver key, length = 10",labelpos = "E")
streamplot(X,Y,U,V)
streamplot(X,Y,U,V,color=U,linewidth=2,cmap=PyPlot.cm[:autumn])
lw = 5 .* speed ./ maximum(speed) # Line Widths
streamplot(X,Y,U,V,density=0.6,color="k",linewidth=lw)
Thanks to Ian Butterworth for providing this example.
axes_grid1 = pyimport("mpl_toolkits.axes_grid1")
divider = axes_grid1.make_axes_locatable(ax)
ax2 = divider.new_vertical(size="100%", pad=0.1)
fig.add_axes(ax2)
ax.spines["top"].set_visible(false)
ax2.spines["bottom"].set_visible(false)
# Upper Line Break Markings
d = 0.015 # how big to make the diagonal lines in axes coordinates
ax2.plot((-d, +d), (-d, +d), transform=ax2.transAxes, color="k", clip_on=false,linewidth=0.8) # Left diagonal
ax2.plot((1 - d, 1 + d), (-d, +d), transform=ax2.transAxes, color="k", clip_on=false,linewidth=0.8) # Right diagonal
# Lower Line Break Markings
ax.plot((-d, +d), (1 - d, 1 + d), transform=ax.transAxes, color="k", clip_on=false,linewidth=0.8) # Left diagonal
ax.plot((1 - d, 1 + d), (1 - d, 1 + d), transform=ax.transAxes, color="k", clip_on=false,linewidth=0.8) # Right diagonal
Hey, thanks a lot for the useful examples!, by the way, do you have one for vector fields and streamplot?