Below I created a simple example of my dataset. I have 4 points and each steps their value change. The points are plotted in x,y positions and the colors change with their value. How i can fix one colorbar useful for each plot?
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.scatter(final[i]['x'],final[i]['y'],c=final[i]['value'])
plt.colorbar()
I have one other question, I want to create an animation of these 3 plots (with the same colorbar) but i'm not able to do that, someone can help me?
For the same colorbar add simply: vmin and vmax to plt.scatter. For example:
for i in range(0,len(final)):
fig, ax = plt.subplots()
plt.scatter(final[i]['x'],final[i]['y'],c=final[i]['value'],vmin=0, vmax=15,)
plt.colorbar()
What kind of animation do you desire? Plot the scatters one by one?
this should do:
fig, axs = plt.subplots(1,3, figsize=(12,3))
for i in range(0,len(final)):
im = axs[i].scatter(final[i]['x'],final[i]['y'],c=final[i]['value'])
fig.colorbar(im, ax=axs.ravel().tolist())
more ideas in this thread: Matplotlib 2 Subplots, 1 Colorbar
For animation - need more details.
Related
I want to draw multiple bar plots with the same y-scale, and so I need the y-scale to be consistent.
For this, I tried using ylim() after yscale()
plt.yscale("log")
plt.ylim(top=2000)
plt.show()
However, python keeps autoscaling the intermittent values depending on my data.
Is there a way to fix this?
overlayed graphs
import numpy as np
import matplotlib.pyplot as plt
xaxis = np.arange(10)
yaxis = np.random.rand(10)*100
fig = plt.subplots(figsize =(10, 7))
plt.bar(xaxis, yaxis, width=0.8, align='center', color='y')
# show graph
plt.yscale("log")
plt.ylim(top=2000)
plt.show()
You can set the y-axis tick labels manually. See yticks for an example. In your case, you will have to do this for each plot to have consistent axes.
I would like to plot multiple PSD obtained with plot_psd() from MNE python.
I tried the following code
import matplotlib.gridspec as gridspec
gs = gridspec.GridSpec(3,1)
plt.figure()
ax = plt.axes()
# First plot
ax1 = fig.add_subplot(gs[0]
raw_egi.plot_psd(ax=ax1)
ax2=fig.add_subplot(gs[1]
raw_ws_ds_hp_lp.plot_psd(ax=ax2)
ax3= fig.add_subplot(gs[2]
raw_ws_ds_hp_lp_nf.plot_psd(ax=ax3)
plt.show()
It tells me that I have an invalid syntax.
The following code is working but all plots are superimposed
import matplotlib.gridspec as gridspec
gs = gridspec.GridSpec(3,1)
plt.figure()
ax = plt.axes()
# First plot
raw_egi.plot_psd(ax=ax)
raw_ws_ds_hp_lp.plot_psd(ax=ax)
raw_ws_ds_hp_lp_nf.plot_psd(ax=ax)
plt.show()
Could you tell me ho to plot these 3 figures without superimposing but vertically (one by row). Bellow you will find the figure with the working code (i.e. 3 superimposed plots) Thanks for your help
Here is how I solve the question for 2 plots
import matplotlib.pyplot as plt
fig, ax = plt.subplots(2)
raw_bp.plot_psd(ax=ax[0], show=False)
raw_bp_nf.plot_psd(ax=ax[1], show=False)
ax[0].set_title('PSD before filtering')
ax[1].set_title('PSD after filtering')
ax[1].set_xlabel('Frequency (Hz)')
fig.set_tight_layout(True)
plt.show()
When you have a 2D plot in matplolib you can change the line width of spines (the containing box) as follows:
fig, ax = plt.subplots()
ax.plot([1,2,3])
spines = ax.spines
[i.set_linewidth(5) for i in spines.values()]
Figure with thick spines:
However this same methodology does not work for 3D plots.
How could I change the axes line thickness for a 3D plot?
You can do this using the following code. I adapted the idea of accessing the axes in 3D from this answer. If you want to change the thickness of all the grid lines as well, refer to this answer by ImportanceOfBeingErnest
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
for axis in [ax.w_xaxis, ax.w_yaxis, ax.w_zaxis]:
axis.line.set_linewidth(5)
I have a matplotlib bar chart, which bars are colored according to some rules through a colormap. I need a colorbar on the right of the main axes, so I added a new axes with
fig, (ax, ax_cbar) = plt.subplots(1,2)
and managed to draw my color bar in the ax_bar axes, while I have my data displayed in the ax axes. Now I need to reduce the width of the ax_bar, because it looks like this:
How can I do?
Using subplots will always divide your figure equally. You can manually divide up your figure in a number of ways. My preferred method is using subplot2grid.
In this example, we are setting the figure to have 1 row and 10 columns. We then set ax to be the start at row,column = (0,0) and have a width of 9 columns. Then set ax_cbar to start at (0,9) and has by default a width of 1 column.
import matplotlib.pyplot as plt
fig = plt.figure(figsize=(8,6))
num_columns = 10
ax = plt.subplot2grid((1,num_columns), (0,0), colspan=num_columns-1)
ax_cbar = plt.subplot2grid((1,num_columns), (0,num_columns-1))
The ususal way to add a colorbar is by simply putting it next to the axes:
fig.colorbar(sm)
where fig is the figure and sm is the scalar mappable to which the colormap refers. In the case of the bars, you need to create this ScalarMappable yourself. Apart from that there is no need for complex creation of multiple axes.
import matplotlib.pyplot as plt
import matplotlib.colors
import numpy as np
fig , ax = plt.subplots()
x = [0,1,2,3]
y = np.array([34,40,38,50])*1e3
norm = matplotlib.colors.Normalize(30e3, 60e3)
ax.bar(x,y, color=plt.cm.plasma_r(norm(y)) )
ax.axhline(4.2e4, color="gray")
ax.text(0.02, 4.2e4, "42000", va='center', ha="left", bbox=dict(facecolor="w",alpha=1),
transform=ax.get_yaxis_transform())
sm = plt.cm.ScalarMappable(cmap=plt.cm.plasma_r, norm=norm)
sm.set_array([])
fig.colorbar(sm)
plt.show()
If you do want to create a special axes for the colorbar yourself, the easiest method would be to set the width already inside the call to subplots:
fig , (ax, cax) = plt.subplots(ncols=2, gridspec_kw={"width_ratios" : [10,1]})
and later put the colorbar to the cax axes,
fig.colorbar(sm, cax=cax)
Note that the following questions have been asked for this homework assignment already:
Point picker event_handler drawing line and displaying coordinates in matplotlib
Matplotlib's widget to select y-axis value and change barplot
Display y axis value horizontal line drawn In bar chart
How to change colors automatically once a parameter is changed
Interactively Re-color Bars in Matplotlib Bar Chart using Confidence Intervals
I am trying to produce a scatter plot that has two different y-axes and also a colorbar.
Here is the pseudo-code used:
#!/usr/bin/python
import matplotlib.pyplot as plt
from matplotlib import cm
fig = plt.figure()
ax1 = fig.add_subplot(111)
plt.scatter(xgrid,
ygrid,
c=be, # set colorbar to blaze efficiency
cmap=cm.hot,
vmin=0.0,
vmax=1.0)
cbar = plt.colorbar()
cbar.set_label('Blaze Efficiency')
ax2 = ax1.twinx()
ax2.set_ylabel('Wavelength')
plt.show()
And it produces this plot:
My question is, how do you use a different scale for the "Wavelength" axes, and also, how do you move the colorbar more to right so that it is not in the Wavelength's way?
#OZ123 Sorry that I took so long to respond. Matplotlib has extensible customizability, sometimes to the point where you get confused to what you are actually doing. Thanks for the help on creating separate axes.
However, I didn't think I needed that much control, and I ended up just using the PAD keyword argument in
fig.colorbar()
and this provided what I needed.
The pseudo-code then becomes this:
#!/usr/bin/python
import matplotlib.pyplot as plt
from matplotlib import cm
fig = plt.figure()
ax1 = fig.add_subplot(111)
mappable = ax1.scatter(xgrid,
ygrid,
c=be, # set colorbar to blaze efficiency
cmap=cm.hot,
vmin=0.0,
vmax=1.0)
cbar = fig.colorbar(mappable, pad=0.15)
cbar.set_label('Blaze Efficiency')
ax2 = ax1.twinx()
ax2.set_ylabel('Wavelength')
plt.show()
Here is to show what it looks like now::
the plt.colorbar() is made for really simple cases, e.g. not really thought for a plot with 2 y-axes.
For a fine grained control of the colorbar location and properties you should almost always rather work with colorbar specifying on which axes you want to plot the colorbar.
# on the figure total in precent l b w , height
cbaxes = fig.add_axes([0.1, 0.1, 0.8, 0.05]) # setup colorbar axes.
# put the colorbar on new axes
cbar = fig.colorbar(mapable,cax=cbaxes,orientation='horizontal')
Note that colorbar takes the following keywords:
keyword arguments:
cax
None | axes object into which the colorbar will be drawn ax
None | parent axes object from which space for a new
colorbar axes will be stolen
you could also see here a more extended answer of mine regarding figure colorbar on separate axes.