3D plotting in Python - Adding a Legend to Scatterplot - python

from mpl_toolkits.mplot3d import Axes3D
ax.scatter(X_lda[:,0], X_lda[:,1], X_lda[:,2], alpha=0.4, c=y_train, cmap='rainbow', s=20)
plt.legend()
plt.show()
Essentially I'd like to add a legend for the scatterplot that shows the unique values in y_train and what color point it corresponds to on the plot.
The output plot:

Producing either a legend or a colorbar for a scatter is usually quite simple:
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
x,y,z = (np.random.normal(size=(300,4))+np.array([0,2,4,6])).reshape(3,400)
c = np.tile([1,2,3,4], 100)
fig, ax = plt.subplots(subplot_kw=dict(projection="3d"))
sc = ax.scatter(x,y,z, alpha=0.4, c=c, cmap='rainbow', s=20)
plt.legend(*sc.legend_elements())
plt.colorbar(sc)
plt.show()

Related

3D scatter with two axes in logscale

I am trying to get a scatter plot with 2 axes (x,z) in a log scale using set_scale but that doesn't work.
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
x=np.linspace(0,500,10)
y=np.linspace(0,1,10)
z=np.linspace(0,100000,10)
fig = plt.figure()
ax = Axes3D(fig)
ax.plot(x, y, z,'o', c='g')
ax.grid()
#ax.set_xscale('log')
#ax.set_zscale('log')
#ax.set_xlim([min(x), max(x)])
#ax.set_zlim([min(z), max(z)])
plt.show()

Matplotlib/Seaborn: how to plot a rugplot on the top edge of x-axis?

Suppose I draw a plot using the code below. How to plot the rug part on the top edge of x-axis?
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
sns.distplot(np.random.normal(0, 0.1, 100), rug=True, hist=False)
plt.show()
The seaborn.rugplot creates a LineCollection with the length of the lines being defined in axes coordinates. Those are always the same, such that the plot does not change if you invert the axes.
You can create your own LineCollection from the data though. The advantage compared to using bars is that the linewidth is in points and therefore no lines will be lost independend of the data range.
import numpy as np; np.random.seed(42)
import matplotlib.pyplot as plt
import seaborn as sns
def upper_rugplot(data, height=.05, ax=None, **kwargs):
from matplotlib.collections import LineCollection
ax = ax or plt.gca()
kwargs.setdefault("linewidth", 1)
segs = np.stack((np.c_[data, data],
np.c_[np.ones_like(data), np.ones_like(data)-height]),
axis=-1)
lc = LineCollection(segs, transform=ax.get_xaxis_transform(), **kwargs)
ax.add_collection(lc)
fig, ax = plt.subplots()
data = np.random.normal(0, 0.1, 100)
sns.distplot(data, rug=False, hist=False, ax=ax)
upper_rugplot(data, ax=ax)
plt.show()
Rugs are just thin lines at the data points. Yo can think of them as thin bars. That being said, you can have a following work around: Plot distplot without rugs and then create a twin x-axis and plot a bar chart with thin bars. Following is a working answer:
import numpy as np; np.random.seed(21)
import matplotlib.pyplot as plt
import seaborn as sns
fig, ax = plt.subplots()
data = np.random.normal(0, 0.1, 100)
sns.distplot(data, rug=False, hist=False, ax=ax)
ax1 = ax.twinx()
ax1.bar(data, height=ax.get_ylim()[1]/10, width=0.001)
ax1.set_ylim(ax.get_ylim())
ax1.invert_yaxis()
ax1.set_yticks([])
plt.show()

How to set a colormap in interactive plot animations in python

The code below creates an animation of 600k points by scatter plotting 30k of them per frame. The animation works flawlessly, except for the fact that I don't know how to include my colormap (Heatintensity) in the animation. The Xs and Ys are changing but the color of the points is just blue.
import numpy as np
import matplotlib.pyplot as plt
Heatintensity=workdata[0:600000] #Values controlling scatter colormap
Xs=xCoord[0:600000]
Ys=yCoord[0:600000]
plt.ion()
fig, ax = plt.subplots()
sc = ax.scatter(Xs, Ys, c=Heatintensity, cmap=cm.jet, s=5)
plt.draw()
for i in range(20):
sc.set_offsets(np.c_[Xs[(i*30000):(i*30000)+30000],\
Ys[(i*30000):(i*30000)+30000]])
fig.canvas.draw_idle()
plt.pause(0.1)
In order to change the colors, you need to use
sc.set_array(Heatintensity[(i*30000):(i*30000)+30000])
in addition to changing the offsets.
In order for the colors to represent the same numerical values for each animation step, the scatter must be normalized to all data,
norm = plt.Normalize(Heatintensity.min(), Heatintensity.max())
Complete example:
import numpy as np
import matplotlib.pyplot as plt
Heatintensity=np.random.rand(600000) #Values controlling scatter colormap
Xs=np.random.rand(600000)
Ys=np.random.rand(600000)
plt.ion()
fig, ax = plt.subplots()
norm = plt.Normalize(Heatintensity.min(), Heatintensity.max())
sc = ax.scatter(Xs, Ys, c=Heatintensity, s=5, cmap=plt.cm.jet, norm=norm)
plt.draw()
for i in range(20):
# set coordinates
sc.set_offsets(np.c_[Xs[(i*30000):(i*30000)+30000],\
Ys[(i*30000):(i*30000)+30000]])
# set colors
sc.set_array(Heatintensity[(i*30000):(i*30000)+30000])
# draw and make pause
plt.pause(0.1)
plt.ioff()
plt.show()
The same can be achieved using a FuncAnimation:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
Heatintensity=np.random.rand(600000) #Values controlling scatter colormap
Xs=np.random.rand(600000)
Ys=np.random.rand(600000)
fig, ax = plt.subplots()
norm = plt.Normalize(Heatintensity.min(), Heatintensity.max())
sc = ax.scatter(Xs, Ys, c=Heatintensity, s=5, cmap=plt.cm.jet, norm=norm)
def update(i):
# set coordinates
sc.set_offsets(np.c_[Xs[(i*30000):(i*30000)+30000],\
Ys[(i*30000):(i*30000)+30000]])
# set colors
sc.set_array(Heatintensity[(i*30000):(i*30000)+30000])
ani = animation.FuncAnimation(fig, update, frames=range(20), interval=100)
plt.show()

Using seaborn and contourf, how can I plot gridlines?

Using the following code, the first contour plot has grid lines. For the second plot, I have imported seaborn, but the grid lines don't show up. What do I need to add to make the grid lines show on the second plot.
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
dx=0.05
x=np.arange(0,5+dx,dx)
y=x
X,Y = np.meshgrid(x,y)
Z = np.sin(X)**10+np.cos(10+Y*Y)*np.cos(X)
nbins=10
levels=mpl.ticker.MaxNLocator(nbins=nbins).tick_values(Z.min(),Z.max())
plt.figure()
plt.contourf(x,y,Z,levels=levels)
plt.colorbar()
plt.grid('on')
import seaborn as sns
sns.set_context("notebook")
sns.set_style("whitegrid")
plt.figure()
plt.contourf(x,y,Z,levels=levels)
plt.colorbar()
plt.grid('on')
plt.show()
You either need to change either the axes.axisbelow rc parameter or the zorder of the contourf plot. So you could do
sns.set(context="notebook", style="whitegrid",
rc={"axes.axisbelow": False})
When you set up the style or
plt.contourf(x, y, Z, levels=levels, zorder=0)
When you draw the plot.

how can I increase the space between tick labels and axes labels in matplotlib for a 3D plot?

how can I increase the space between tick labels and axes labels in matplotlib for a 3D plot?
my plot is defined in this way
import pylab
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
from matplotlib import cm
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.scatter(np.log10(NP), np.log10(NB*10**12), np.log10(NL), c='r', marker='o', lw=0)
ax.scatter(np.log10(NPd), np.log10(NBd), np.log10(NLd), c='b', marker='o', lw=0)
ax.set_xlabel('Periods', fontsize=35)
ax.set_ylabel('Magnetic', fontsize=35)
ax.set_zlabel('Luminosity', fontsize=35)
atockx = ax.xaxis.get_major_ticks()
for tockx in atockx:
tockx.label.set_fontsize(30)
atocky = ax.yaxis.get_major_ticks()
for tocky in atocky:
tocky.label.set_fontsize(30)
atockz = ax.zaxis.get_major_ticks()
for tockz in atockz:
tockz.label.set_fontsize(30)

Categories

Resources