matplotlib surface plot with hidden zaxis - matplotlib

when I change the viewpoint of plot_surface in matplolib in (90,0), the zaxis is not clear, and it's useless in this plot. I want to generate the image same as matlab as below
matlab surf with view (0,90),with contour lines
I used matplotlib function imshow can generate matrix image, but there are no lines (similar in contourplot lines)in the image. how can i generate the image with plot_surface in python with a viewpoint of (90,0),bu without zaxis?
matplotlib with plot_surface,view(90,0),withou lines and zaxis

You can use contourf from matplotlib:
import matplotlib.pyplot as plt
import numpy as np
X, Y = np.meshgrid(range(100), range(100))
Z = X**2+Y**2
plt.contourf(X, Y, Z, [i for i in np.linspace(Z.min(),Z.max(),30)])
plt.show()
, which results in:

Related

Scale Y axis of matplotlib plot in jupyter notebook

I want to scale Y axis so that I can see values, as code below plots cant see anything other than a thin black line. Changing plot height doesn't expand the plot.
import numpy as np
import matplotlib.pyplot as plt
data=np.random.random((4,10000))
plt.rcParams["figure.figsize"] = (20,100)
#or swap line above with one below, still no change in plot height
#fig=plt.figure(figsize=(20, 100))
plt.matshow(data)
plt.show()
One way to do this is just repeat the values then plot result, but I would have thought it possible to just scale the height of the plot?
data_repeated = np.repeat(data, repeats=1000, axis=0)
You can do it like this:
import numpy as np
import matplotlib.pyplot as plt
data=np.random.random((4, 10000))
plt.figure(figsize=(40, 10))
plt.matshow(data, fignum=1, aspect='auto')
plt.show()
Output:

Is there a way to draw shapes on a python pandas plot

I am creating shot plots for NHL games and I have succeeded in making the plot, but I would like to draw the lines that you see on a hockey rink on it. I basically just want to draw two circles and two lines on the plot like this.
Let me know if this is possible/how I could do it
Pandas plot is in fact matplotlib plot, you can assign it to variable and modify it according to your needs ( add horizontal and vertical lines or shapes, text, etc)
# plot your data, but instead diplaying it assing Figure and Axis to variables
fig, ax = df.plot()
ax.vlines(x, ymin, ymax, colors='k', linestyles='solid') # adjust to your needs
plt.show()
working code sample
import pandas as pd
import matplotlib.pyplot as plt
import seaborn
from matplotlib.patches import Circle
from matplotlib.collections import PatchCollection
df = seaborn.load_dataset('tips')
ax = df.plot.scatter(x='total_bill', y='tip')
ax.vlines(x=40, ymin=0, ymax=20, colors='red')
patches = [Circle((50,10), radius=3)]
collection = PatchCollection(patches, alpha=0.4)
ax.add_collection(collection)
plt.show()

how to draw axes passing through the origin in a 3D plot using matplotlib

I want to create a 3d plot like the following, such that axes pass through the origin with ticks on them.
PS: I could do that for 2D plots using matplotlib (the following figure). I searched a lot to do the same for 3D plots but I did not find any info.
If you want to restrict yourself to just matplotlib then we can use quiver3d plot as shown below. But the results may not be very visually appealing. You can see here how to add 3D text annotations.
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import numpy as np
fig = plt.figure()
ax = fig.add_subplot(111,projection='3d')
ax.set_xlim(0,2)
ax.set_ylim(0,2)
ax.set_zlim(0,2)
ax.view_init(elev=20., azim=32)
# Make a 3D quiver plot
x, y, z = np.zeros((3,3))
u, v, w = np.array([[1,1,0],[1,0,1],[0,1,1]])
ax.quiver(x,y,z,u,v,w,arrow_length_ratio=0.1)
plt.show()

Joining the points in a scatter plot

I’ve a scatter plot which almost looks like a circle. I would like to join the outer points with a line to show that almost circle like shape. Is there a way to do that in matplotlib?
You can use ConvexHull from scipy.spatial to find the outer points of your scatter plot and then connect these points using a PolyCollection from matplotlib.collections:
from matplotlib import pyplot as plt
import numpy as np
from scipy.spatial import ConvexHull
from matplotlib.collections import PolyCollection
fig, ax = plt.subplots()
length = 1000
#using some normally distributed data as example:
x = np.random.normal(0, 1, length)
y = np.random.normal(0, 1, length)
points = np.concatenate([x,y]).reshape((2,length)).T
hull = ConvexHull(points)
ax.scatter(x,y)
ax.add_collection(PolyCollection(
[points[hull.vertices,:]],
edgecolors='r',
facecolors='w',
linewidths=2,
zorder=-1,
))
plt.show()
The result looks like this:
EDIT
Actually, you can skip the PolyCollection and just do a simple line plot using the hull vertices. You only have to make the line circular by appending the first vertex to the list of vertices (making that list one element longer):
circular_hull_verts = np.append(hull.vertices,hull.vertices[0])
ax.plot(
x[circular_hull_verts], y[circular_hull_verts], 'r-', lw=2, zorder=-1,
)
EDIT 2:
I noticed that there is an example in the scipy documentation that looks quite similar to mine.

pyplot color chart of 2d function domain

How can I make a 2-d color plot of the domain of a function across two dimensions? Something like this:
def f(x):
return x[0]**2+6*x[1]**2+x[0]*x[1]+np.sin(x[0])+3*x[0]
x = np.arange(-5,5,0.1)
y = np.arange(-5,5,0.1)
plt.contours(x,y,f([x,y])
Change your last line to
plt.contour(f(np.meshgrid(x,y)))
That will evaluate f across a meshed grid of x and y and plot contours of that function. The tutorial on producing contour plots in matplotlib is here. In general, the tutorials there are pretty good and you can often find what you want.
If you want the axes labelled with the ranges in your x and y ranges - you need
plt.contour(x,y,f(np.meshgrid(x,y)))
You could instead do plt.pcolormesh(f(np.meshgrid(x,y))) if you prefer a 'heatmap' style to a contour plot.
For fun, I expanded the range and amplified the sin component in your function and produced a contour map and a heatmap (see output)
import matplotlib.pyplot as plt
import numpy as np
def f(x):
return x[0]**2+6*x[1]**2+x[0]*x[1]+150*np.sin(x[0])+3*x[0]
x = np.arange(-50,50,0.1)
y = np.arange(-50,50,0.1)
plt.contour(x,y,f(np.meshgrid(x,y)))
plt.show()
Contour output
pcolormesh output