I have problems when drawing horizontal bar chart
firstly if we draw it in plt.bar
plt.figure(figsize=(8,5))
plt.bar(range_df.range_start, range_df.cum_trade_vol, width=30)
plt.show()
but if we draw it in plt.barh
plt.figure(figsize=(8, 5))
plt.barh(range_df.range_start, range_df.cum_trade_vol)
plt.show()
its either
or like:
The problem, I think, is because the crowded data that left too few gaps.
What can we do to properly draw the graph? (since we cannot set width with barh? or can we?)
Maybe another plot package?
Please do not reset the y axis value as the current value is important
The data can be downloaded at
https://drive.google.com/file/d/1y8fHazEFhVR_u2KL6uUsBqv0qmXOd2xT/view?usp=share_link
the notebook is at:
https://colab.research.google.com/drive/1MbjJE4B-mspDRqCYXnDf8hyFRK_uLmRp?usp=sharing
Thank you
I am somewhat unsure of what you are talking about. When writing the horizontal plot, you drop width parameter. There is an equivalent version for plt.barh which is height. So try
plt.barh(range_df.range_start, range_df.cum_trade_vol, height=30)
Related
Solved: This problem occurred with matplotlib 3.4, updating to 3.5 fixed the issue.
I am plotting multiple subplots in a graph, which all have titles, labels and subplot titles. To keep everything visible and the right size, I am using constrained_layout.
I would like to add a title that is aligned to the left. However, when I specify the x position (even as 0.5 which is the default), the title overlaps with the graph.
My plots are much more complex, but this already shows my issue:
import matplotlib.pyplot as plt
import numpy as np
fig = plt.figure(figsize=(10, 5), constrained_layout=True)
gs = fig.add_gridspec(1,1)
ax1 = fig.add_subplot(gs[0,0])
fig.suptitle('Title', ha='left')
Only changing the last line of code:
fig.suptitle('Title with x-position', x=0.5, ha='left')
I was first using tight layout, but switched to constrained_layout because tight_layout did not keep the specified size of the figure when exporting it.
I have also switched from subplots to gridspec because I read that constrained_layout does not support subplots.
I know I can add extra space with fig.set_constrained_layout_pads(h_pad=0.3), but this also adds space below the plots, which I would like to avoid.
Hopefully someone can tell me why this happens and how I can get a title aligned to the left that does not overlap with the plot!
The problem occurred in Matplotlib 3.4, updating to 3.5 fixed the issue
Hello there!
I am trying to create a figure consisting of a chloropleth map and a bar plot in Matplotlib. To achieve this, i am using the Geopandas library alongside Pandas and Matplotlib. I've run into an interesting problem that i couldn't find any answer for on the internet. Here's the problem:
This link leads to an image that replicates the problem.
As it can be seen on the image above, the map on the top (generated by Geopandas) does not span the same width as the bar chart on the bottom. There is too much whitespace to the left and the right of the figure. I want to get rid of this whitespace and make the map fit horizontally on the space that is allocated to it. I am also leaving a code sample below for those who wish to recreate it:
fig = plt.figure(figsize = (25.60,14.40)) #Here, i am setting the overall figure size
ax_1 = fig.add_subplot(2,1,1) #This will be the map
istanbul_districts.plot(ax = ax_1,
edgecolor = "black",
alpha = 1,
color = "Red") #Istanbul_districts is a GeoDataFrame object.
ax_2 = fig.add_subplot(2,1,2)
labels = list(health.loc[:,"district_eng"].value_counts().sort_values(ascending = False).index)
from numpy import arange
bar_positions = arange(len(labels)) + 1
bar_heights = h_inst_per_district_eng.loc[:,"health_count"].values.astype(int)
ax_2.bar(bar_positions,bar_heights,
width = 0.7,
align = "center",
color = "blue") #This is a generic barplot from Matplotlib
I am leaving a second image that shows the end result of the code snippet above:
This link also leads to an image that replicates the problem.
It can be clearly seen above that the axes of the two subplots do not start and end on the same location. Perhaps that could be the problem? What can be done to make them the same size?
Thanks to all those answer for their time in advance!
Adding an explanation, since you have found one solution.
If you specify matplotlib figure with two axes in a way you did, you get the figure split in half. Both axes are the same. Let's say that the original ratio of the figure is 1:1, your axes will be both 1:2.
This arbitrary ratio is fine for a bar chart, which can be scaled to essentially any ratio. It does not matter much if it is horizontal or vertical (from a plotting perspective, not data-viz).
However, if you want your map to show correct non-distorted shapes, you can't just specify the aspect ratio. That just follows the data. So if you have a map, which bounding box has 1:1 ratio, you can't expect that it will fill the whole 1:2 axis. GeoPandas changes the aspect ratio to follow the map's ratio.
The reason why the first example leaves gaps on side and the "solution" does not is this. Because the leftover space is on top and on the bottom the axis, it is not shown in the solution. Because it is on sides in the issue, it just stays there. If you had your plots next to each other instead of above, it would be vice versa.
Hope it is clearer.
Hello again!
swatchai's comment set me up on the right track and i found the culprit. Simply adjusting the figsize to a value like (19,19) fixed the problem. I'd still be happy if anyone can explain exactly why this happens.
Here's what it looks like when the figsize is a square (19,19):
Thanks for your efforts!
All,
I'm trying to export figures in (roughly) a particular size so I can include them in high-res in my LaTeX document. When I draw the figure, the ylabel is cutoff (I assume because my figure is small, 2.7in wide). When I call tight_layout(), I get the labels fine, but now the axes are no longer center in the saved image. I need the axes centered above the caption, so I want the axes centered on the image.
I tried adding a second axis to the right side, but I couldn't figure out how to make the labels and ticks invisible for that axis.
Here is without tight_layout()
Here is with tight_layout()
Any idea how I can get the best of both worlds (everything visible, with the axes centered)?
Thanks!
I also encountered this problem and it seems there is no elegent way after I googled it. I ended up with the fig.subplots_adjust.
import matplotlib.pyplot as plt
fig = plt.figure()
plt.plot([10,20,30])
plt.xlabel('xlabel')
plt.ylabel('ylabel')
fig.patch.set_facecolor('silver')
fig.set_size_inches(w=3.5, h =3)
# %%
#fig.tight_layout()
plt.subplots_adjust(left=0.15, right=0.85, bottom=0.15, top=0.9)
fig.savefig('test.png')
But this will produce additional padding around the axes and tedious parameter-tuning...
while fig.tight_layout() produces:
It would be nice to test it on the code. But try playing with axes.set_position() as shown here: https://www.google.com/amp/s/www.geeksforgeeks.org/matplotlib-axes-axes-set_position-in-python/amp/
I am aware of how to plot a line graph on top of scatter plot of the same data but is there a way to bring the line graph forward so it sits on top of the markers rather than behind?
Example code:
import numpy as np
x=np.array([1,2,3,4,5])
y=np.array([1,2,3,4,5])
plt.errorbar(x,y,xerr=0.1,yerr=0.1, fmt="x",markersize=5, color = "orange")
plt.plot(x,y)
This code outputs a scatter graph with a line graph behind it. When you increase the number of data points it becomes harder to see the line behind them all. Other than decreasing the marker size can I bring the line on top of all the points?
I think you are intending to draw things at different levels of z-order on the screen. This is done like such:
plt.plot(x,y, zorder=10)
Note 10 is arbitrarily large and this will likely plot on top of your legend too, so you may need to adjust it!
You can use the option barsabove=True. This places the error bars above the markers and the line is displayed on the top of error bars and markers. To highlight this effect, I am using a thick error bar. As you can see, the blue line lies above the error bars and markers. Use barsabove=False (default value) to see the difference.
x=np.array([1,2,3,4,5])
y=np.array([1,2,3,4,5])
plt.errorbar(x,y,xerr=0.1,yerr=0.1, linewidth=10, fmt="x",markersize=5, color = "orange", barsabove=True)
plt.plot(x,y)
I'm trying to plot a swarmplot with seaborn but I'm struggling with the legend of the plot, I managed to change its position if the figure, but now it is cropped and no information is shown:
I moved the legend with:
plt.legend(bbox_to_anchor=(1.05, 1), loc=2, borderaxespad=0.)
I changed the size of the figure with no luck
plt.figure(figsize=(12, 10))
I also tried tight_layout() but it just removes the legend from the plot.
Any ideas on how to make it appear on the side of the plot nicely without any cropping on the side or bottom?
Thank you
The legend is not taken into account when plt.tight_layout() tries to optimize the spaces. However you can set the spaces manually using
plt.subplots_adjust()
The relevant argument here is the right side of the figure, so plt.subplots_adjust(right=0.7) would be a good start. 0.7 means that the right part of the axes is at 70% of the total figure size, which should give you enough space for the legend.
Then, you may want to change that number according to your needs.
You can do that like this.
# Import necessary libraries
import seaborn as sns
import matplotlib.pyplot as plt
# Initialize Figure and Axes object
fig, ax = plt.subplots(figsize=(10,4))
# Load in the data
iris = sns.load_dataset("iris")
# Create swarmplot
sns.swarmplot(x="species", y="petal_length", data=iris, ax=ax)
# Show plot
plt.show()
Result is here
Source
(its too late maybe i know but i wanted to share i found already)