Empty circles with errorbars - python

How can I make a python plot with empty circles and error bars? I see I can use facecolors='none' for a scatter plot, but it is not working for errorbar plot. I also found mfc='none' which makes the circles empty, but the error bars are still visible inside the circles. How can I make it such that the circles are completely empty, and the error bars come out only from outside of the circles (the errorbars are bigger than the size of the data points)?Thank you!

One option is to plot with mfc the same color with the background color, e.g. mfc='w':
y = [1,2,3,4]
yerr=[.1,.2,.3,.4]
plt.figure(figsize=(10,6))
plt.errorbar(x=y,y=y, yerr=yerr, ms=30, marker='o', mfc='w')
Output:
However, there is a risk as you can see above, when the marker size is larger than the error, you don't get to see the error bars.

Related

Using plot and scatter on same figure with different colors but even if I plot first, the scatter still show up UNDER the plot

I am plotting a distribution of variables that are outputs from two different versions of a program. They look very similar (this is great because they should!) and I am showing their ratio in the same figure but on a different axis. My goal is to show the ratio as a scatter plot but with a horizontal line at y=1.0 to show 100% agreement. The issue I am having is even if I plot the line first and then the scatter, my scatter points still show underneath the line plot. (Please see the image linked below.) You can see the scatter in black underneath the line plot in red, even though I call the plot function first. Any recommendations? Thank you!
Distribution of two variables with ratio plot underneath

enlarging the figure in the pop-out window in matplotlib

How to enlarge a figure inside the pop-out window? I use the following code to generate my figure:
self._fig = plt.figure()
#self._fig = plt.figure(figsize=(2,1)) # tried this, didn't work, only change the size of the pop-out window, but now the figure itself
ax1 = self._fig.add_subplot(211,projection='3d')
# some code for plotting the lines and drawing the spherical surfaces, which is not shown here
ax1.set_xlim(-6,6)
ax1.set_ylim(-6,6)
ax1.set_zlim(-15,15)
ax1.set_aspect(2.5, 'box') # the axis limit and aspect limit is chosen so that the whole figure has the same scale in all directions
#ax1.view_init(elev=90, azim=0)
ax1.set_xlabel('X-axis')
ax1.set_ylabel('Y-axis')
ax1.set_zlabel('Z-axis')
ax1.grid(True)
You can see that there is lot of unused space in the pop-out window, and the figure looks really small. I want to maximize the size of the figure so that it fills the whole pop-out window. Now even if I manually enlarge the pop-out window, the figure still looks the same.
I tried varying the axis limits, but it doesn't seem to work. I tried setting the
figsize in the first line, but it only changes the size of the pop-out window, but the figure itself.
Another problem is that I want to change the 'camera-view' of the figure so that the z-axis (the lone axis) is horizontal. Again, I tried a range of different values in ax.view_init, but I can't get the view I want. I only allows me rotate around the z-axis, while what I need to do is to rotate around x or y-axis by 90deg.
Try calling plt.tight_layout()
before you call plt.show()

Matplotlib: Intelligent figure scale / legend location

Some code gives me the following matplotlib figure:
Unfortunately, the figure size is fixed and hence on the top right, the legend and the lines overlap. Is there any way to have the legend not stack on top of the lines?
I am aware that legend allows ax2.legend(loc=0), where 0 will put it into the "best" location. However, with two y axis as here, this will stack both legends on top of each other - not really the best allocation.
My next best try would be to "scale up" the figure, as manually done with an interactive graph, where I have only scaled up both axis:
Doing this with the "real" figure scale requires iterated "trying numbers and checking how far it goes" procedure - which may need to be redone if the graph changes. Is there any way of having matplotlib compute the scale "intelligently"?
If the best location plt.legend(loc='best') fails, try putting the legend outside of the plot:
plt.legend(loc='upper left', bbox_to_anchor=(1.02, 1), borderaxespad=0)
You can scale only legend, not the whole plot. Link here
More on legends here and also here.

Margins in 2D image plot after adding scatterplot point in Matplotlib

I am trying to label points on the image, but whenever I do an extra marker on the plots by coordinate values and the margins becomes unnecessarily large. What is the issue here, and is there a way to fix this?
The image is fine. I even plotted it below and everything seems okay when I don't add the plotted point.
imp = plt.imshow(processed[::-1],cmap='gray_r',vmin=1000,vmax=2000)
plt.colorbar()
plt.figure()
imp = plt.imshow(processed[::-1],cmap='gray_r',vmin=1000,vmax=2000)
plt.plot(600,400,'*',color='r')
plt.colorbar()
Large Margin around image generated

Matplotlib - multiple surface plots, wrong overlapping

I am currently plotting two completely different datasets into one 3D surface plot. When I am plotting each one independently, everything works fine. However, as soon as I plot them in one, the visualization is strange. I do the plotting the following way:
fig = plt.figure(figsize=(20,10))
ax = fig.add_subplot(111, projection='3d')
ax.plot_surface(X,Y,Z, color=color, antialiased=True)
(get new X,Y, Z values)
ax.plot_surface(X,Y,Z, color=color, antialiased=True)
ax.view_init(30, 360)
The output is the following:
As you can see, the blue data is correct, but the green one is somehow in the backside and not correctly visualized. If I plot the green one alone, it works perfectly.
Changing the order of plotting (or playing around with zorder) does not change anything.
Hope someone can help!
Matplotlib is just a 2d plotting library. 3d plots are achieved by projecting the 3d surface onto the image plane.
If you have multiple 3d surfaces, it will turn each into a 2d shape, and then calculate a single height for each shape, and show then in that order.
As far as I'm aware, the zorder option doesn't work, and all it would is change the order of the surfaces anyway.
If you're really unlucky, the grey boxes that make up the axis grids can get plotted above your surface too. That's even more annoying.
Of you must use matplotlib, then i guess you could split up your surface into lots of smaller ones, but you're going to encounter a pretty big performance bit doing this, and you'll to override the values in the legend too.

Categories