Python Pyplot won't plot surface fully - python

In the attached picture you can see two plots of the same data. The left one is plotted with plot_wireframe() the right one with plot_surface()
Like this:
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.plot_surface(xm, ym, Values)
fig2 = plt.figure()
ax2 = fig2.add_subplot(111, projection='3d')
ax2.plot_wireframe(xm, ym, Values)
plt.show()
Why is this? The plot_wireframe is correct. Why is for example the peak in the left upper corner not shown on the surface plot? Thanks
Here, another example with the data matrix:

Given what the discussion in the comments, I think what's going on is you have a normal wireframe that looks as it should, but the surface plot is a 2D projection in that 3D axes object. I noticed that you are missing a line that shows up in the matplotlib surface example: X, Y = np.meshgrid(X, Y). Assuming I'm on the right track, you need to insert an analogous statement prior to the axes.plot_surface() call.

Related

Matplotlib: Subplot heights with squared imshow

I want to plot a three-panel figure, with an imshow on the top and two other plots below. My imshow is has the same x and y dimensions, ie. is squared. The two other plots have the same x dimension, they can therefore share the x axis. However, how do I specify that all three panels have the same width?
This is my code
import matplotlib.pyplot as plt
x = np.linspace(0,100,20)
y = np.sin(x)
z = np.random.rand(100,100)
fig, (ax, ax2, ax3) = plt.subplots(nrows=3, sharex=True, figsize=(10,10), gridspec_kw={"height_ratios": [2,1,1]})
# "main" plot
ax.imshow(z)
# accessory plot #1
ax2.plot(x, y)
ax2.set_xlim(0,99)
# accessory plot #2
ax3.plot(x*2, y)
plt.show()
I don't understand the behavior here, why does my imshow not have the correct width like the two panels below?
I found a solution here, but as far as I understand this can only create one additional axis per side?
This is my current output:
And I would like it to look like this:
Layout is defnitely something matplotlib could use some work on. What is happening is that you have a square figure, with height_ratios=[2, 1, 1]: the first axis (where you plot the image) has double the height of the other two. But the image you are plotting is also square, so it is using all the available height, while it has "white" space on the horizontal direction.
Try to play with figsize and maybe the height_ratios, something like this:
fig, (ax, ax2, ax3) = plt.subplots(nrows=3, sharex=True, figsize=(6,12), gridspec_kw={"height_ratios": [4,1,1]})

Matplotlib: Grid over the surface of a 3D plot with three (1D) arrays

I have 3(1D) arrays so to plot a surface as far as I know the only thing I can use is TRISURF. But I don´t know how to put a grid over the surface,like this plot
This is the part of my code I´m having problem with:
fig = plt.figure()
ax = Axes3D(fig)
surf = ax.plot_trisurf(x, y, z,cmap=plt.cm.get_cmap('jet',256), linewidth=0.5, antialiased=True)
Thanks, a lot.

Plotting histograms on the back planes of 3D plots in matplotlib

Using matplotlib, I am attempting to display the histograms of 2 sets of data simultaneously on the side walls of a 3D plot, using this Matlab code and plot from wikipedia as my guide: https://commons.wikimedia.org/wiki/File:MultivariateNormal.png
I am able to plot my raw data on the base plane and have created and plotted my Gaussian fits on the side walls using the 'zdir' kwarg.
This example is able to leverage the 'zdir' kwarg to force where the curves are plotted,
Matplotlib 2d Plot on Faces of 3d Plot
but the matplotlib documentation confirms my AttributeErrors: Unknown property zdir; hist and hist2d don't support this argument.
This example seems to be plotting bars manually on the figure
plotting 3d histogram/barplot in python matplotlib as a way around the problem.
I've tried both .hist and .hist2d with and without zdir=''.
# data is a 2D np.array defined elsewhere
# define plot limits
X = np.linspace(0, np.amax(data), 100)
Y = np.linspace(0, np.amax(data), 100)
# initialize data into x and y sets
x_data = data[:, 0]
y_data = data[:, 1]
# fit a gaussian to both sets
x_mean, x_std = norm.fit(x_data)
x_gauss = norm.pdf(X, x_mean, x_std)
y_mean, y_std = norm.fit(y_data)
y_gauss = norm.pdf(Y, y_mean, y_std)
# initialize plot
figure = plt.figure()
ax = figure.add_subplot(111, projection='3d')
# label axes
ax.set_xlabel('Delta X (um)')
ax.set_ylabel('Delta Y (um)')
ax.set_zlabel('P (X,Y)')
# plot data on base plane
ax.scatter3D(x_data, y_data, zdir='z', zs=0.0, c='k', marker='.')
# plot histograms on walls
ax.hist((x_data, x_gauss), bins=30) #these 2 lines
ax.hist((y_data, y_gauss), bins=30) #are where I'm looking for help
# plot gaussians on walls
ax.plot3D(X, x_gauss, zdir='y', zs=np.amax(data), c='b')
ax.plot3D(Y, y_gauss, zdir='x', zs=np.amax(data), c='g')
# show plot
plt.show()
Is there a direct match in matplotlib for the method Matlab that draws histograms on a specific plane of a 3D plot? Thank you for your help! I am very new to plotting and welcome any other idiomatic or depreciated changes you can see. I always like to see how other coders think.

Change the color of the plot depending on the density (stored in an array) in line plot in matplotlib

I have a file with three columns, lets say, x y z. I need to plot x Vs y but I need to change the color of that (x,y) value depending on its density (stored in z column). I understand that I need to use color map and have to map the values of the color with the z array. I can do that via scatter plot as also shown in this post: How can I make a scatter plot colored by density in matplotlib?
But I do not need the scatter plot, I need the points to be connected, ie I need a line plot. Can it be done in line plot?
It's not possible to connect points from a scatter plot directly. But the same effect can be achieved by plotting a line behind the scatter points.
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(-3,6)
y = np.sin(x)
z = 0.5+np.random.rand(len(x))
fig, ax = plt.subplots()
ax.plot(x, y, color="k", marker=None, zorder=0)
sc = ax.scatter(x, y, c=z, s=100, edgecolor='',zorder=3)
plt.colorbar(sc, label="Density")
plt.show()

Set the plot y-axis and x-axis ratio equal

import numpy as np
import matplotlib.pyplot as plt
plt.figure(1)
plt.subplot(211)
xs = np.linspace(-5,5,500)
ys = np.sqrt(5**2 - xs**2)
plt.plot(xs,ys)
plt.plot(xs,-ys)
plt.subplot(212)
plt.plot(xs, xs**2)
plt.show()
here is the code i generate, was wondering that if i want keep the upper plot x and y ratio be 1:1 so that the ball will always look round no matter how many subplot inside this figure.
I tried to find it from the website, seems not a simple solution..
When you create your subplot, you can tell it:
plt.subplot(211, aspect='equal')
If you've already created the subplot, you have to grab the current axes, which you can do using plt.gca, then call the set_aspect method:
plt.gca().set_aspect('equal')
Or, you can keep track of the axes from the beginning:
ax = plt.subplot(211)
ax.set_aspect('equal')
You may have to call
plt.draw()
In order to update the plot.

Categories