There is an example for how to build a bar plot at the bottom of this question taken from the matplotlib site.
I cannot find a parameter to increase the depth of each bar. I want depth to give it a 3d look like this picture.
Is there a function parameter to change this that I'm not seeing, or will I need to use a different 3D bar plot function?
Below is the bar plot code from the first link in case someone can't see it:
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import numpy as np
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
for c, z in zip(['r', 'g', 'b', 'y'], [30, 20, 10, 0]):
xs = np.arange(20)
ys = np.random.rand(20)
# You can provide either a single color or an array. To demonstrate this,
# the first bar of each set will be colored cyan.
cs = [c] * len(xs)
cs[0] = 'c'
ax.bar(xs, ys, zs=z, zdir='y', color=cs, alpha=0.8)
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
plt.show()
I've found this link to a solution but this solution doesn't actually increase the depth. I'm hoping for a method to completely fill the depth if possible.
Do you want something like the code in this answer? They use bar3d(), but the locations for each bar are manually created with meshgrid.
Related
I have three variables for my plot and I colour by the fourth variable. I have made a scatter plot via the following code, but I want a contour plot. My code:
import numpy as np
import matplotlib.pyplot as plt
a=np.linspace(4.0,14.0,3)
b=np.linspace(0.5,2.5,3)
c=np.linspace(0.0,1.0,3)
d=np.random.rand(len(a),len(b),len(c)) #colour by this variable
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
z,y,x=np.meshgrid(c,a,b)
img = ax.scatter(x, y, z, c=d, cmap='RdGy')
fig.colorbar(img, pad=0.2).set_label('colour')
ax.set_xlabel('c')
ax.set_ylabel('a')
ax.set_zlabel('b')
I want a filled contour instead of scatter plot. I know mayavi.mlab has this feature, but I cannot import mlab for some reason. Is there an alternative, or is there a better way of presenting this data?
Here is how I would present this 3-dimensional data. Each plot is a cross-section through the cube. This makes sense intuitively.
import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(4.0, 14.0, 3)
y = np.linspace(0.5, 2.5, 3)
z = np.linspace(0.0, 1.0, 3)
data = np.random.rand(len(x), len(y), len(z))
fig, axes = plt.subplots(len(z), 1, figsize=(3.5, 9),
sharex=True,sharey=True)
for i, (ax, d) in enumerate(zip(axes, data.swapaxes(0, 2))):
ax.contour(x, y, d)
ax.set_ylabel('y')
ax.grid()
ax.set_title(f"z = {z[i]}")
axes[-1].set_xlabel('x')
plt.tight_layout()
plt.show()
My advice: 3D plots are rarely used for serious data visualization. While they look cool, it is virtually impossible to read any data points with any accuracy.
Same thing goes for colours. I recommend labelling the contours rather than using a colour map.
You can always use a filled contour plot to add colours as well.
I've been working on matplotlib's secondary-yaxis and I can't figure out how I should set "functions" parameter in order to get the result that I want.
I want to make a semi-log plot and set set the labels of y-ticks in the 2 following formats:
ordinary format such as "10^1, 10^2, 10^3, ..., 10^(exponent), ..."
the exponents only: "1, 2, 3, ..."
And I want to put them in the former style in the y-axis of left side, and the latter right side.
What I want to do can be done by using twinx() like this:
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(1, 3, 41)
y = 10**x
fig, ax1 = plt.subplots()
ax1.set_yscale('log')
ax1.plot(x, y)
ax2 = ax1.twinx()
ymin, ymax = ax1.get_ylim()
ax2.set_ylim(np.log10(ymin), np.log10(ymax))
plt.show()
You would see that i=(1, 2, 3) in the right label is located at the same height as 10^i in the left label.
However, I want to know how to do the same thing by secondary_yaxis. I've tried this but it didn't work.
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(1, 3, 41)
y = 10**x
fig, ax = plt.subplots()
ax.set_yscale('log')
ax.plot(x, y)
def forward(x):
return np.log10(x)
def backward(x):
return 10**x
secax = ax.secondary_yaxis('right', functions=(forward, backward))
plt.show()
It resulted in this:
You can see right-side tick labels are broken. I suspect that my way of setting the parameter "functions" of secondary_yaxis() might be invalid. I would appreciate it if you tell me how to do it.
I get the broken figure on matplotlib 3.1.0. and updating it to 3.3.0. has solved the problem. The same code as the second code block of the question generates this.
enter image description here
Below I created a simple example of my dataset. I have 4 points and for each steps their value change. The points are plotted in x,y plane and I want their size to change with their value. There is also one other problem, each point is connected by a line and I don't want it. (I cannot use plt.scatter)
import pandas as pd
import matplotlib.pyplot as plt
data=[[1,1,3],[1,2,1],[2,1,9],[2,2,0]]
a=pd.DataFrame(data)
a.columns=['x','y','value']
data2=[[1,1,5],[1,2,2],[2,1,1],[2,2,3]]
b=pd.DataFrame(data2)
b.columns=['x','y','value']
data3=[[1,1,15],[1,2,7],[2,1,4],[2,2,8]]
c=pd.DataFrame(data3)
c.columns=['x','y','value']
final=[a,b,c]
for i in range(0,len(final)):
fig, ax = plt.subplots()
plt.plot(final[i]['x'],final[i]['y'],marker='o',markersize=22)
with this I fix the dimension the line appears in, how can I remove it?
If I change the markersize, it doesn't work:
for i in range(0,len(final)):
fig, ax = plt.subplots()
plt.plot(final[i]['x'],final[i]['y'],marker='o',markersize=final[i]['value'])
As I said before, the result I want is a plot in which there are only the points with different dimensions depending on their value.
Since you cannot use scatter, you need to loop over the values to use the markersize as it does not accept arrays but a scalar. Moreover, to just plot a marker, you use 'o' for a circle. I used size*5 to enlarge the circles further.
for i in range(0,len(final)):
fig, ax = plt.subplots()
for x, y, size in zip(final[i]['x'],final[i]['y'], final[i]['value']):
plt.plot(x, y, 'o', markersize=size*5)
In case you want to plot them as subplots
fig, axes = plt.subplots(1,3, figsize=(9, 2))
for i in range(0,len(final)):
for x, y, size in zip(final[i]['x'],final[i]['y'], final[i]['value']):
axes[i].plot(x, y, 'o', markersize=size*5)
plt.tight_layout()
You have an argument for the line width in plt.plot graphs. Please set it to zero.
plt.plot(final[i]["x"], final[i]["y"], marker="o", markersize=22, linewidth=0)
I produce multiple plots containing each 5 subplots, generated in a for loop.
How can I define the coloring of the subplots? Do I need something like a Matrix with numbers and colors and use it somehow like Matrix[z] instead of the Color?
fig = plt.figure()
ax = fig.add_subplot(111)
for z in Var
ax.plot(x, y, color='black', alpha=0.5 , label=labelString)
It is unclear what you exactly mean. But if you mean plotting 5 different curves in the same plot, each in different color, this is one way you can do it. This allows you to choose colors as you want. In case you do not specify colors manually like in the code below, python will assign colors automatically. In that case you just have to write ax.plot(x, y, label=r'y=%dx$^2$' %(i+1))
import numpy as np
import matplotlib.pyplot as plt
fig = plt.figure(figsize=(8, 5))
ax = fig.add_subplot(111)
colors = ['r', 'g', 'b', 'k', 'y']
x = np.linspace(0, 5, 100)
for i in range(5):
y = (i+1)*x**2
ax.plot(x, y, color=colors[i], label=r'y=%dx$^2$' %(i+1))
plt.legend(fontsize=16)
Output
I have the following problem:
I want to plot an adjacency matrix using a colormap. Now I want do adjust the markersize, because you cannot really
see the dots in the picture since the matrix is really big . How can I do this? Using spy(), this works like this.
plt.spy(adj, markersize = 1)
I want to have something like this:
plt.imshow(adj, cmap = colormap, markersize= 1)
This however, doesnt work.
Thanks
You may use a scatter plot, which allows to set the markersize using the s argument.
ax.scatter(X,Y,c=z, s=36, marker="s")
An example comparing a spy, imshow and scatter plot.
import matplotlib.pyplot as plt
import numpy as np
fig, (ax1,ax2,ax3) = plt.subplots(ncols=3, figsize=(8,4))
z = np.random.rand(20, 20)
X,Y = np.meshgrid(np.arange(z.shape[1]),np.arange(z.shape[0]))
z[5] = 0.
z[:, 12] = 0.
ax1.spy(z, markersize=5, precision=0.1, origin="lower")
ax2.imshow(z, origin="lower")
ax3.scatter(X,Y,c=z, s=36, marker="s")
ax3.set_aspect("equal")
ax3.margins(0)
ax1.set_title("spy")
ax2.set_title("imshow")
ax3.set_title("scatter")
plt.show()