Can't print all Legend in a 3D graph with matplotlib - python

I have a dataset like:
I can't get the graph to print the 4 labels I'm plotting, the labels are the keys on this dictionary:
a = {'Pike':'red','Roach':'blue','Bream':'green','Perch':'orange'}
It will only print the first one:
from matplotlib.pyplot import plot, show, draw, figure, cm
from mpl_toolkits.mplot3d import Axes3D
sns.set_style("whitegrid", {'axes.grid' : False})
fig = plt.figure(figsize=(8,8))
ax = Axes3D(fig)
#ax = fig.add_subplot(111, projection='3d')
a = {'Pike':'red','Roach':'blue','Bream':'green','Perch':'orange'}
b = a.keys()
x = fish['Height']
y = fish['Width']
z = fish['Weight']
mp = ax.scatter(x, y, z, c=fish['Species'].apply(lambda x: a[x]), alpha=0.5, marker='o', s=50)
ax.view_init(azim=30)
ax.view_init(elev=15)
ax.set_xlabel('Height', fontweight ='bold')
ax.set_ylabel('Width', fontweight ='bold')
ax.set_zlabel('Weight', fontweight ='bold')
#ax.legend(a.keys(), bbox_to_anchor=(1.0, 1), loc=1)
legend = ax.legend(a.keys(), loc="upper left", title="Species", ncol=4)
ax.add_artist(legend)
plt.title('Fish Features 3d', fontweight ='bold', size=40)
plt.show()

Related

make a circle from dots using python

Could some help me to draw a circle using matplotlib or matplotlib and numpy. I have a set of points with x and y coordinates. set of points
Then I need to take from this set dots that will make a circle. The result should be something a circle
import numpy
import matplotlib.pyplot as plt
X = list(range(1, 101))
Y = list(range(1, 101))
x = numpy.array(X)
y = numpy.array(Y)
xgrid, ygrid = numpy.meshgrid(x, y)
plt.style.use('seaborn')
fig, ax = plt.subplots()
ax.scatter(xgrid, ygrid, s=5, color='green')
ax.set_title('net 100х100',
fontfamily = 'monospace',
fontstyle = 'normal',
fontweight = 'bold',
fontsize = 10)
ax.set_xlabel("X", fontsize=14)
ax.set_ylabel("Y", fontsize=14)
ax.tick_params(axis='both', which='major', labelsize=14)
ax.axis([0, 101, 0, 101])
plt.show()
All you need to do is collect the points that are in the circle.
import matplotlib.pyplot as plt
xgrid = []
ygrid = []
for x in range(100):
for y in range(100):
if (x-50)*(x-50)+(y-50)*(y-50) < 25*25:
xgrid.append(x)
ygrid.append(y)
plt.style.use('seaborn')
fig, ax = plt.subplots()
ax.scatter(xgrid, ygrid, s=5, color='green')
ax.tick_params(axis='both', which='major', labelsize=14)
ax.axis([0, 101, 0, 101])
plt.show()

Plot matplotlib histogram legend on separate figure

Given a line plot obtained with ax.plot(), I have the following handy code to plot the legend on a separate figure:
fig, ax = plt.subplots()
ax.plot([0, 2], label='a', linestyle='--')
ax.plot([-1, 1], label='b', linestyle='dotted')
fig = plt.figure(figsize=(30, 4), constrained_layout=True)
fig.legend(ax.lines, [l.get_label() for l in ax.lines],
loc="upper center")
However if I do this with a histogram (using ax.hist()), ax.lines is empty and I cannot get the labels and styles used. Is it possible to do that still ?
import matplotlib.pyplot as plt
import numpy as np
fig, ax = plt.subplots()
x = np.random.randn(1000, 3)
colors = ['red', 'tan', 'lime']
_,_,patches = ax.hist(x, 10, color=colors, label=colors)
fig = plt.figure(figsize=(30, 4), constrained_layout=True)
fig.legend([p[0] for p in patches], [p[0].get_label() for p in patches],
loc="upper center")
UPDATE as per comment: you can achieve the same using ax.patches instead of patches returned by ax.hist like so:
import matplotlib.pyplot as plt
import numpy as np
fig, ax = plt.subplots()
x = np.random.randn(1000, 3)
colors = ['red', 'tan', 'lime']
n_bins = 10
ax.hist(x, n_bins, color=colors, label=colors)
fig = plt.figure(figsize=(3, 4), constrained_layout=True)
fig.legend(ax.patches[::n_bins], [p.get_label() for p in ax.patches[::n_bins]], loc="upper center")

Dual Y-axis horizontal line position access in stratx plot

I want to draw a horizontal line going through the 0.0 point over the plot produced by stratx's (https://github.com/parrt/stratx) plot_stratpd method.
How can I access the left Y-axis in this case, so that I can use y=0.0?
from stratx.partdep import *
X = df.drop('user_retained', axis=1)
y = df['user_retained']
plt.figure(figsize=(16,16), dpi= 80, facecolor='w', edgecolor='k')
plot_stratpd(X, y, 'percentage_of_points', 'user_retained', yrange=(-0.3, 0.6), n_trials=10)
plt.tight_layout()
plt.axhline(y=134, alpha=1, linewidth = 2, linestyle = '-')
plt.show()
Set up an Axes and pass it to plot_stratpd. You can then use this Axes to plot the horizontal line at regular data coordinates:
fig,ax = plt.subplots(figsize=(16,16), dpi= 80, facecolor='w', edgecolor='k')
plot_stratpd(X, y, 'percentage_of_points', 'user_retained', yrange=(-0.3, 0.6), n_trials=10, ax=ax)
ax.axhline(y=0, alpha=1, linewidth = 2, linestyle = '-')
Example:
from sklearn.datasets import load_diabetes
from stratx.partdep import *
import matplotlib.pyplot as plt
diabetes = load_diabetes()
df = pd.DataFrame(diabetes.data, columns=diabetes.feature_names)
df['y'] = diabetes.target
X = df.drop('y', axis=1)
y = df['y']
fig,ax = plt.subplots()
plot_stratpd(X, y, 'bmi', 'y', n_trials=10, ax=ax)
ax.axhline(0)
plt.show()

How to make an animation over different values of n here?

I have written a code that plot some points and lines on the xy plane. It plots everything for a given value of n. So for different n I get my desired plots. But I want to animate these plots for different values of n, say, for n=1, 2, ..., 100. But I cannot do this animation.
Can anyone here help me to do this? Thank you.. I paste my code here:
My Code
import matplotlib as mpl
mpl.rc('text', usetex = True)
mpl.rc('font', family = 'serif')
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.patches import Circle
fig = plt.subplots()
ax = plt.axes(xlim=(-1.2, 1.2), ylim=(-1.2, 1.2))
plt.gca().set_aspect('equal', adjustable='box')
plt.style.use(['ggplot','dark_background'])
plt.rcParams['figure.figsize'] = (12, 8)
n = 10 #I want to animate this n.
p = 2
for k in range(0,n,1):
theta1 = np.pi + 2*k*np.pi / n
theta2 = np.pi + 2*p*k*np.pi / n
x, y = np.cos(theta1), np.sin(theta1)
x1, y1 = np.cos(theta2), np.sin(theta2)
plt.scatter(x, y, s=50, c='violet', zorder=3)
plt.plot([x,x1], [y,y1], color = 'w')
circle = plt.Circle((0, 0), 1, color='c', fill=False, lw = 1)
ax.add_artist(circle)
#Customize the axes and gridlines:
ax.grid(False)
ax.spines['right'].set_visible(False)
ax.spines['top'].set_visible(False)
ax.spines['left'].set_visible(False)
ax.spines['bottom'].set_visible(False)
#TickMarks Customization:
ax.set_xticks([])
ax.set_yticks([])
#plt.savefig('nthRoots.png', format='png', dpi=1000,bbox_inches='tight')
plt.show()
Output
Is it possible to animate n over different values?
EDIT: Here I donot have only scatter plots ...so I cannot understand how to do this job using those links..!
My Attempt
#Animation.
import matplotlib as mpl
mpl.rc('text', usetex = True) #for LaTex notation in the Plot
mpl.rc('font', family = 'serif')
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.patches import Circle
from matplotlib import animation, rc
rc('animation', html='html5')
fig = plt.subplots()
ax = plt.axes(xlim=(-1.2, 1.2), ylim=(-1.2, 1.2))
plt.gca().set_aspect('equal', adjustable='box')
plt.style.use(['ggplot','dark_background'])
plt.rcParams['figure.figsize'] = (12, 8)
p = 2
#Plotting Function:
def f(n):
for k in range(0,n,1):
theta1 = np.pi + 2*k*np.pi / n
theta2 = np.pi + 2*p*k*np.pi / n
x, y = np.cos(theta1), np.sin(theta1)
x1, y1 = np.cos(theta2), np.sin(theta2)
plt.scatter(x, y, s=50, c='violet', zorder=3)
plt.plot([x,x1], [y,y1], color = 'w')
circle = plt.Circle((0, 0), 1, color='c', fill=False, lw = 1)
ax.add_artist(circle)
#Customize the axes and gridlines:
ax.grid(False)
ax.spines['right'].set_visible(False)
ax.spines['top'].set_visible(False)
ax.spines['left'].set_visible(False)
ax.spines['bottom'].set_visible(False)
#TickMarks Customization:
ax.set_xticks([])
ax.set_yticks([])
plt.show()
#Now I try to define a function for animating n in f(n)
def animate(n):
f(n)
anim = animation.FuncAnimation(fig, animate,
frames=100, interval=100, blit=True)
#anim.save('Wave.mp4', writer = 'ffmpeg', fps = 2, dpi=500,extra_args=['-vcodec', 'libx264'])
That's all I had... But this idea didn't work...I think I have to properly define animate(n).
Any suggestion...! thanks.
Several problems in your code (most are unrelated to animations)
rcParams need to be defined before creating the figure
plt.subplots returns a tuple of figure and axes.
The animation must return a sequence of artist objects when blitting is used. You might turn it off though
plt.show() should be called once at the end of the script.
Correcting for those you get
import matplotlib as mpl
mpl.rc('font', family = 'serif')
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.patches import Circle
from matplotlib import animation, rc
plt.rcParams['figure.figsize'] = (12, 8)
plt.style.use(['ggplot','dark_background'])
fig, ax = plt.subplots()
p = 2
#Plotting Function:
def f(n):
ax.clear()
ax.set(xlim=(-1.2, 1.2), ylim=(-1.2, 1.2))
ax.set_aspect('equal', adjustable='box')
for k in range(0,n,1):
theta1 = np.pi + 2*k*np.pi / n
theta2 = np.pi + 2*p*k*np.pi / n
x, y = np.cos(theta1), np.sin(theta1)
x1, y1 = np.cos(theta2), np.sin(theta2)
plt.scatter(x, y, s=50, c='violet', zorder=3)
plt.plot([x,x1], [y,y1], color = 'w')
circle = Circle((0, 0), 1, color='c', fill=False, lw = 1)
ax.add_artist(circle)
#Customize the axes and gridlines:
ax.grid(False)
ax.spines['right'].set_visible(False)
ax.spines['top'].set_visible(False)
ax.spines['left'].set_visible(False)
ax.spines['bottom'].set_visible(False)
#TickMarks Customization:
ax.set_xticks([])
ax.set_yticks([])
anim = animation.FuncAnimation(fig, f, frames=100, interval=100, blit=False)
plt.show()

Matplotlib: how to set a tick label above a plot

This is the sine and cosine plot I draw using matplotlib. But the tick labels are below the plot and can hardly seen.
My python code is:
import numpy as np
import matplotlib.pyplot as plt
fig = plt.figure(figsize=(8,6), dpi=96)
plt.subplot(111)
X = np.linspace(-np.pi, np.pi, 256, endpoint=True)
C,S = np.cos(X), np.sin(X)
plt.plot(X, C, color="blue", linewidth=2.5, linestyle="-", label="consine")
plt.plot(X, S, color="red", linewidth=2.5, linestyle="-", label="sine")
plt.xlim(X.min()*1.1, X.max()*1.1)
plt.ylim(C.min()*1.1, C.max()*1.1)
plt.xticks([-np.pi, -np.pi/2, 0, np.pi/2, np.pi],
[r'$-\pi$', r'$-\frac{\pi}{2}$', r'$0$', r'$+\frac{\pi}{2}$', r'$+\pi$'])
plt.yticks([-1, 1],
[r'$-1$', r'$+1$'])
ax = plt.gca()
ax.spines['right'].set_color('none')
ax.spines['top'].set_color('none')
ax.xaxis.set_ticks_position('bottom')
ax.spines['bottom'].set_position(('data',0))
ax.yaxis.set_ticks_position('left')
ax.spines['left'].set_position(('data',0))
plt.legend(loc='upper left', frameon=False)
for label in ax.get_xticklabels()+ax.get_yticklabels():
label.set_fontsize(16)
label.set_bbox(dict(facecolor='green', edgecolor='None', alpha=0.2))
plt.savefig("figures/exercise10.png", dpi=120)
plt.show()
So, how should I set a tick label above a plot?
Thank you!
Possibly you want to set the labels and the axes spines on top of the lines. This can easily be achieved with the "axes.axisbelow" rcParam.
plt.rcParams["axes.axisbelow"] = False

Categories

Resources