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.
Related
I've recently gotten into plotly and am absolutely loving it, so am trying to use it in each project I do.
With matplotlib I can plot a line plot and a scatter plot on the same graph using the code below.
plt.figure(figsize = (20,5))
plt.scatter(x, y)
plt.plot(x, y_pred, color = "r")
plt.show()
Using the trendline parameter in the scatter function inside plotly.express I can plot a line of best fit through the scattered points, but I don't want that as I am trying to demonstrate how to calculate that line.
Thanks for the help in advance!
Using same defined arrays / lists, x, y, y_pred. An equivalent approach is to use Plotly Express to create a figure then add additional traces to it.
import pandas as pd
import numpy as np
import plotly.express as px
x = np.linspace(1, 20, 16)
y = np.random.uniform(1, 6, 16)
y_pred = y * 1.1
fig = px.scatter(x=x, y=y, color_discrete_sequence=["yellow"])
fig.add_traces(px.line(x=x, y=y_pred, color_discrete_sequence=["red"]).data)
You can use fig.add_shape after you have created the scatter plot like so:
fig.add_shape(
type="line",
x0=0,
y0=0,
x1=10,
y1=10,
line=dict(width=1, dash="dash"),
)
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
I have a code to plot a figure.
When I run this code without adding plt.colorbar(), I can get a figure which looks more like a rectangle. However, if I add colorbar, the shape change to look like a square.
How can I add colorbar and maintain the original shape of the figure? Thanks!!!
#%%
import numpy as np
import matplotlib.pyplot as plt
fig = plt.figure()
x = np.random.rand(10000)
y = np.random.rand(10000)
plt.scatter(x,y,c=y)
#plt.colorbar()
plt.show()
Following this documentation, you need to add some settings to axes. Your script works for me in a right ways if I insert these rows after creation of fig:
ax = plt.gca()
ax.set_aspect('equal', 'box')
I am trying to use ax.scatter to plot a 3D scattering plot. I've read the data from a fits file and stored data from three column into x,y,z. And I have made sure x,y,z data are the same size. z has been normolized between 0 and 1.
import numpy as np
import matplotlib
from matplotlib import pylab,mlab,pyplot,cm
plt = pyplot
import pyfits as pf
from mpl_toolkits.mplot3d import Axes3D
import fitsio
data = fitsio.read("xxx.fits")
x=data["x"]
y=data["y"]
z=data["z"]
z = (z-np.nanmin(z)) /(np.nanmax(z) - np.nanmin(z))
Cen3D = plt.figure()
ax = Cen3D.add_subplot(111, projection='3d')
cmap=cm.ScalarMappable(norm=z, cmap=plt.get_cmap('hot'))
ax.scatter(x,y,z,zdir=u'z',cmap=cmap)
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_zlabel('z')
plt.show()
What I am trying to achieve is use color to indicate the of size of z. Like higher value of z will get darker color. But I am keep getting a plot without the colormap I want, they are all the same default blue color. What did I do wrong? Thanks.
You can use the c keyword in the scatter command, to tell it how to color the points.
You don't need to set zdir, as that is for when you are plotting a 2d set
As #Lenford pointed out, you can use cmap='hot' in this case too, since you have already normalized your data.
I've modified your example to use some random data rather than your fits file.
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
x = np.random.rand(100)
y = np.random.rand(100)
z = np.random.rand(100)
z = (z-np.nanmin(z)) /(np.nanmax(z) - np.nanmin(z))
Cen3D = plt.figure()
ax = Cen3D.add_subplot(111, projection='3d')
ax.scatter(x,y,z,cmap='hot',c=z)
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_zlabel('z')
plt.show()
As per the pyplot.scatter documentation, the points specified to be plotted must be in the form of an array of floats for cmap to apply, otherwise the default colour (in this case, jet) will continue to apply.
As an aside, simply stating cmap='hot' will work for this code, as the colour map hot is a registered colour map in matplotlib.
I am trying to simply fill the area under the curve of a plot in Python using MatPlotLib.
Here is my SSCCE:
import json
import pprint
import numpy as np
import matplotlib.pyplot as plt
y = [0,0,0,0,0,0,0,0,0,0,0,863,969,978,957,764,767,1009,1895,980,791]
x = np.arange(len(y))
fig2, ax2 = plt.subplots()
ax2.fill(x, y)
plt.savefig('picForWeb.png')
plt.show()
The attached picture shows the output produced.
Does anyone know why Python is not filling the entire area in between the x-axis and the curve?
I've done Google and StackOverflow searches, but could not find a similar example. Intuitively it seems that it should fill the entire area under the curve.
I usually use the fill_between function for these kinds of plots. Try something like this instead:
import numpy as np
import matplotlib.pyplot as plt
y = [0,0,0,0,0,0,0,0,0,0,0,863,969,978,957,764,767,1009,1895,980,791]
x = np.arange(len(y))
fig, (ax1) = plt.subplots(1,1);
ax1.fill_between(x, 0, y)
plt.show()
See more examples here.
If you want to use this on a pd.DataFrame use this:
df.abs().interpolate().plot.area(grid=1, linewidth=0.5)
interpolate() is optional.
plt.fill assumes that you have a closed shape to fill - interestingly if you add a final 0 to your data you get a much more sensible looking plot.
import numpy as np
import matplotlib.pyplot as plt
y = [0,0,0,0,0,0,0,0,0,0,0,863,969,978,957,764,767,1009,1895,980,791,0]
x = np.arange(len(y))
fig2, ax2 = plt.subplots()
ax2.fill(x, y)
plt.savefig('picForWeb.png')
plt.show()
Results in:
Hope this helps to explain your odd plot.