Need help in understanding how to 3d surface plot using plotly - python

I am trying to plot a function z= sinx cosy over -pi to pi
This is what I'm hoping to get
Also shown like this
This is the code I have written in an attempt to do the same:
import plotly.graph_objs as go
from scipy.linalg import toeplitz
x=np.linspace(-np.pi,np.pi,30)
z = [(np.sin(i)*np.cos(i)) for i in x]
fig = go.Figure(data=[go.Surface(x=x, y=x, z=toeplitz(z))])
fig.show()
plotly output that I'm getting
I have not been able to understand what 'grid' or '2d array' format I have to convert my z co-ordinate column data into for getting the right graph. Toeplitz was an attempt to do the same, but it seems symmetric unlike the required graph. Please help

I think I've got it, if you're facing similar issue you can refer/use the code below
import numpy as np
import plotly.graph_objs as go
f = lambda x,y: np.sin(x) * np.cos(y)
x = np.linspace(-np.pi, np.pi, 30)
y = np.linspace(-np.pi, np.pi, 30)
X,Y = np.meshgrid(x,y)
F = f(X,Y)
fig = go.Figure(data=[go.Surface(x=X, y=Y, z=F)])
fig.show()

Related

How to plot 3D surface plots using Plotly in Python?

I am able to get a Surface Plot using matplotlib with this code:
ax = figure.gca(projection = "3d")
ax.plot_surface(meshed_slopes, meshed_intercepts, errors.reshape(1, meshed_slopes.shape[0]), cmap = cm.autumn_r)
But when I try to do the same using Plotly I get a blank graph.
This is the code am using to plot the surface plot-
import plotly.graph_objects as go
import numpy as np
meshed_slopes, meshed_intercepts = np.meshgrid(slopes, intercepts)
fig = go.Figure(go.Surface(
x = meshed_slopes,
y = meshed_intercepts,
z = errors.reshape(1, meshed_slopes.shape[0])
))
fig.show()
How can I fix this?
Thanks in advance!!!
Since you haven't provided the data so we can take a look I'm going to explain what plotly needs to make the plot work :
x and y needs to be both (n,) shape and same shape
z should be a matrix or a table with (n,n) size
I would suggest a dataframe as it might be easier for you to create everything
(Since I have low rep, I can't write comments so I'm posting this as an answear)
Make sure that x, y, z are 2D arrays.
import plotly.graph_objects as go
import numpy as np
x, y = np.mgrid[-2:2:50j, -2:2:50j]
z = np.cos(x**2 + y**2)
fig = go.Figure([
go.Surface(x=x, y=y, z=z)
])
fig

How to show bigger the distance between two curves in Matplotlib

I wrote a code to plot two curves passing through two data sets. However, after plotting, it turned out that the distance is little. Therefore, I need to rescale the y-axis to show the distance clearly in the resulting figure. But I do not know how to do this.
The code is this:
import numpy as np
from scipy.interpolate import make_interp_spline
import matplotlib.pyplot as plt
# Dataset
x = np.array([41/300,46/300,65/300,69/300,73/300,75/300,81/300,87/300,101/300,116/300,122/300,128/300])
y = np.array([186.492147/100,185.1351/100,181.1801/100,179.8990/100,178.0152/100,177.4235/100,176.8346/100,175.6332/100,173.8296/100 ,
172.0626/100,171.4815/100, 170.9044/100])
X_Y_Spline = make_interp_spline(x, y)
X_ = np.linspace(x.min(), x.max(), 500)
Y_ = X_Y_Spline(X_)
u = np.array([50/300,54/300,66/300,72/300,74/300,75/300,101/300,102/300,110/300,113/300,116/300,118/300,130/300])
v = np.array([183.724636117654/100,182.900/100,180.886911726436/100,178.160318153782/100,177.626286563695/100,
177.403672688541/100,173.695126295789/100,173.666369492423/100,172.52494955916/100,172.273125402593/100,
171.888413653382/100, 171.633213514319/100,170.670417094034/100])
uv_Spline = make_interp_spline(u,v)
U_ = np.linspace(u.min(), u.max(), 500)
V_ = uv_Spline(U_)
plt.plot(U_, V_,linewidth=0.5)
plt.plot(X_, Y_,linewidth=0.5)
plt.show()
I want to show clearly that these two curves have enough distances between themselves somewhere in their domain. Is there any way to do so? I do not know whether to rescale the y-axis? If so, what is is syntax?
I would appreciate any hint.

Plotly library not showing markers in 3D scatter plot

In the default tutorial provided by plotly, the following produces a nice image, and has markers appearing on the plot (in accordance with https://plotly.com/python/3d-scatter-plots/#3d-scatter-plot-with-plotly-express):
import plotly.graph_objects as go
import numpy as np
# Helix equation
t = np.linspace(0, 10, 50)
x, y, z = np.cos(t), np.sin(t), t
fig = go.Figure(data=[go.Scatter3d(x=x, y=y, z=z,mode='markers')])
fig.show()
However if I try to plot some random scatter as follows:
import plotly.graph_objects as go
import numpy as np
x = np.random.randn(10,1)
fig = go.Figure(data=[go.Scatter3d(x=x, y=x, z=x,mode='markers')])
fig.show()
Nothing shows. It is a blank axis with no markers appearing. Would anyone happen to know why?
I've tried to change dimensions, transpose, variable names etc, but still nothing?
It will work if you flatten the array, e.g. if you add x = x.flatten() before the plot.

Generating a 3D sine curve using python

I want to generate a 3D sine curve in python. Does lumpy support it or is there another library I can use for it?
Generating a 2D curve is straightforward something like this --
x = numpy.linspace(0, 20, 0.1)
y = numpy.sin(x)
I now have x and y I can save to disk.
Now I want to do something similar but for a 3D sine curve over x, y and z axes. I am hoping someone might have done it before and help me.
EDIT: I have realized that for my use case I want a 2D curve in 3D space. So the other axes can be constant. So I am simply generating a 2D curve and adding a constant third parameter value to get the x,y,z values.
You can try something like:
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
x = np.arange(0, 20, 0.1)
y = np.sin(x)
z = y*np.sin(x)
fig = plt.figure()
ax = plt.axes(projection='3d')
c = x + y
ax.scatter(x, y, z, c=c)
or maybe you want z = x*np.sin(x) or even z = np.sin(y)
Edit: maybe this is the best solution z = np.sin(np.sqrt(x**2+y**2)) from here
Have a play and to find what you want. Pretty funky stuff and depends on exactly what output you are looking for.

How to slice list from matplotlib ginput

I have a list of values in Python, which I'm plotting with matplotlib. I'm then trying to use ginput in matplotlib to click two points on the graph, from which the X coordinates will be taken, between which to slice my original list. However, I can't seem to find a way to do this.
I already have a list of numbers called MIList, and the following code isn't working for me:
startinput = plt.ginput(2)
print("clicked", startinput)
startinputxvalues = [x[0] for x in startinput]
print(startinputxvalues)
x1 = startinputxvalues[0]
print(x1)
x2 = startinputxvalues[1]
print(x2)
slicedMIList = [MIList[int(x1):int(x2)]]
plt.plot(slicedMIList)
This gives me an array, but it doesn't plot these values on my graph - does anyone have any input as to what I'm doing wrong?
Thanks
The main point is that you need to redraw the canvas, once changes have been made to it. So in order for the new plot to become visible you can call
plt.gcf().canvas.draw()
Here is a complete working code:
import matplotlib.pyplot as plt
import numpy as np
X = np.arange(10)
Y = np.sin(X)
plt.plot(X, Y)
startinput = plt.ginput(2)
x, y = zip(*startinput)
Ysliced = Y[int(x[0]):int(x[1])+1]
Xsliced = X[int(x[0]):int(x[1])+1]
plt.plot(Xsliced, Ysliced, color="C3", linewidth=3)
#draw the canvas, such that the new plot becomes visible
plt.gcf().canvas.draw()
plt.show()

Categories