Skip to content

Instantly share code, notes, and snippets.

@Balinus
Forked from gizmaa/Plot_Examples.md
Created November 22, 2016 21:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Balinus/fb9457ab17f10eced2eefcbae760dc4c to your computer and use it in GitHub Desktop.
Save Balinus/fb9457ab17f10eced2eefcbae760dc4c to your computer and use it in GitHub Desktop.
Various Julia plotting examples using PyPlot

Plotting

Last Update: November 4, 2016
Offline Version

Contents

PyPlot

Translating

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)

--

Important Note

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.

--

Basic Plot

Most of the basic commands in PyPlot are very similar to Matlab.

p = plot(x,y)
xlabel("X")
ylabel("Y")
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.

--

Plot Annotation

(IJulia, Code)

Annotation Examples

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=Dict("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")

--

Time Customization

(IJulia,Code)

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)

Custom Time

--

Subplots

(IJulia, Code)

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

2x2 Subplot

3x1 Subplot

3x1 Touching Subplots

--

Polar and Windrose Plot

(IJulia, Code)

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, required when doing additional modifications

Wind Rose - Bar Plot

Wind Rose - Line Plot

--

Histogram

(IJulia, Code)

h = PyPlot.plt.hist(x,nbins) # Histogram, PyPlot.plt required to differentiate with conflicting hist command

Histogram

--

Bar Plot

(IJulia, Code)

b = bar(x,y,color="#0f87bf",align="center",alpha=0.4)
b = barh(x,y,color="#0f87bf",align="center",alpha=0.4)

Bar Plots

--

Errorbar Plot

(IJulia, Code)

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

Erro Bar Plot

--

Inexact Plot

(IJulia, Code)

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

Inexact XKCD Plot

--

Pie Chart

(IJulia, Code)

p = pie(sizes,labels=labels,shadow=true,startangle=90,explode=explode,colors=colors,autopct="%1.1f%%",textprops=font)

Pie Chart

--

Scatter Plot

(IJulia, Code)

scatter(x,y,s=areas,alpha=0.5)

Scatter Plot

--

Box Plot

(IJulia, Code)

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)

Box Plot

--

Major and Minor Ticks

(IJulia, Code)

###########################
#  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)
ax[:xaxis][:set_tick_params](which="minor",length=5,width=2)

fig[:canvas][:draw]() # Update the figure

Major and Minor Ticks

--

Multi-axis Plot

(IJulia, Code)

################
#  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 = ["color"=>"purple"]
ylabel("Right Axis",fontdict=font2)
p = plot_date(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 = ["color"=>"green"]
ylabel("Far Right Axis",fontdict=font3)
p = plot_date(x,y3,color="green",linestyle="-",marker="o",label="Third") # Plot a basic line
ax3[:set_position](new_position) # Position Method 2
setp(ax3[: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

Multi-axis Plot

--

Axis Placement

(IJulia, Code)

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

Axis Placement

--

Surface and Contour Plots

(IJulia, Code)

Thanks to Daniel Høegh for providing this example.

ax[:plot_surface](xgrid, ygrid, z, rstride=2,edgecolors="k", cstride=2,
   cmap=ColorMap("gray"), alpha=0.8, linewidth=0.25)
cp = ax[:contour](xgrid, ygrid, z, colors="black", linewidth=2.0)
ax[:clabel](cp, inline=1, fontsize=10)

Surface Plot

--

Line Collection

(IJulia, Code)

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)))

c = Vector{Int}[[1,0,0],[0,1,0],[0,0,1]] # Colors

# Assemble everything into a LineCollection
line_segments = matplotlib[:collections][:LineCollection](lines,colors=c)

fig = figure("Line Collection Example")
ax = axes()
ax[:add_collection](line_segments)
axis("image")

Line Collection

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment