How can I plot something above a negative stacked bar chart using Matplotlib Python? - matplotlib

wish you a good day ! I must plot something like that using matplotlib : enter image description here
The standard ax.bar() function does not easily plot stacked bar charts with negative values, that's why I used dataframe.plot(stacked = True) to plot this bar. The problem is that I need to plot a line plot above this bar chart. This line should use the second vertical axis, so I need to get the current matplotlib axis object used by my dataframe.plot(stacked = True) function, I need to twinx() it and then plot the line on the twined axis.
However these 3 things do not work :
enter image description here
which gives :
enter image description here
enter image description here
which gives :
enter image description here
and
enter image description here
which gives :
enter image description here
I dont know what is going wrong, I know the problem stems from the dataframe.plot(stacked = True) function which is the only one that stacks easily bar charts with negative values.

Related

Create a stacked bar chart from data frame

got this data frame which i want to make into a stacked bar chart with the columns on the x axis
enter image description here
tried using barplot but just recive error 'height' must be a vector or a matrix
tried using ggplot(dataframe) and just returns grey rectangle

TramineR legend position and axis

I'm working with TraMineR and I don't know how to arrange my plot. So basically what i would like to have the legend under the plot and to remove the space between the x and y axis. Any help is welcomed.
The plot:
Sample code:
seqdplot(Activities.seq, with.legend=FALSE)
legend("bottom", legend=attr(Activities.seq, "labels"),
fill=attr(Activities.seq, "cpal"),
inset=-.1, bty="o", xpd=NA, cex=.75,ncol=3)
The family of seqplot functions offers a series of arguments to control the legend as well as the axes. Look at the help page of seqplot (and of plot.stslist.statd for specific seqdplot parameters).
For instance, you can suppress the x-axis with axes=FALSE, and the y-axis with yaxis=FALSE.
To print the legend you can let seqdplot display it automatically using the default with.legend=TRUE option and control it with for examples cex.legend for the font size, ltext for the text. You can also use the ncol argument to set the number of columns in the legend.
The seqplot functions use by default layout to organize the graphic area between the plots and the legend. If you need more fine tuning (e.g. to change the default par(mar=c(5.1,4.1,4.1,2.1)) margins around the plot and the legend), you should create separately the plot(s) and the legend and then organize them yourself using e.g. layout or par(mfrow=...). In that case, the separate graphics should be created by setting with.legend=FALSE, which prevents the display of the legend and disables the automatic use of layout.
The color legend is easiest obtained with seqlegend.
I illustrate with the mvad data that ships with TraMineR. First the default plot with the legend. Note the use of border=NA to suppress the too many vertical black lines.
library(TraMineR)
data(mvad)
mvad.scode <- c("EM", "FE", "HE", "JL", "SC", "TR")
mvad.seq <- seqdef(mvad, 17:86,
states = mvad.scode,
xtstep = 6)
# Default plot with the legend,
seqdplot(mvad.seq, border=NA)
Now, we suppress the x and y axes and modify the display of the legend
seqdplot(mvad.seq, border=NA,
axes=FALSE, yaxis=FALSE, ylab="",
cex.legend=1.3, ncol=6, legend.prop=.11)
Here is how you can control the space between the plot and the x and y axes
seqdplot(mvad.seq, border=NA, yaxis=FALSE, xaxis=FALSE, with.legend=FALSE)
axis(2, line=-1)
axis(1, line=0)
Creating the legend separately and reducing the left, top, and right margins around the legend
op <- par(mar=c(5.1,0.1,0.1,0.1))
seqlegend(mvad.seq, ncol=2, cex=2)
par(op)

Matplotlib stacked bar chart not showing all bars

I will make a stacked bar chart in matplotlib. Somehow it doesnt include all the bar chart that i gave him (there should be like 50 bar charts stacked on each other)
The code:
N=45 #numbers of columns
max_el=50
ind=np.arrange(N)
for bar in range(0,max_el):
y=[dic[value][bar] for value in dic]
plt.bar(ind,y,)
plt.show()
note: I used the similar code and same data and made a stacked bar chart with plotly (which worked)
With plotly
With matplotlib
Some of the values of variables are zeros or 0.1. Could that be the problem ?
As described in the comments, you need to add a bottoms array that keeps track of how much each should be moved up from the 0 line. Otherwise, they all start plotting a 0 and overplot one another, with the tallest one sticking up to its values and each one hiding those that were plotted before.

How to control mouseover text in matplotlib

When you mouseover an image shown with imshow, you can mouseover the image to inspect its RGB values. The bottom-right corner of the matplotlib window (sharing space with the toolbar), shows the image coordinates and RGB values of the pixel being pointed at:
x = 274.99 y = 235.584 [.241, .213, .203]
However, when I mouseover a quiver plot, it only shows the x and y coords of the pointer, but not the value of the 2D vector being pointed at. Is there a way to get the vector values to show up?
I would be fine with writing a custom mouse event handler, if I only knew how to set that bit of text in the matplotlib window.
There were times when the information about the color value was not present by default. In fact I think the current version is based on some code that came up in Stackoverflow on some question about that feature.
I quickly found those two questions:
matplotlib values under cursor
Interactive pixel information of an image in Python?
The idea would be to change the function that is called when the mouse hovers the axes. This function is stored in ax.format_coord. So a possible solution is to write your custom function to return the desired output based on the input coordinates, e.g. something like
def format_coord(x, y):
try:
z = # get value depending on x,y, e.g. via interpolation on grid
# I can't fill this because the kind of data is unknown here
return "x: {}, y: {}, z: {}".format(x,y,z)
except:
return "x: {}, y: {}".format(x,y)
ax.format_coord = format_coord

matplotlib: plot or scatter without line through marker

is there a simple way to have scatter() plots (or just plots) with data points shown by some marker and connected by lines, but, when markerfacecolor='none' (or facecolor=none) have the line not shown within the area of the marker.
E.g.:
xx = arange(0.0,10.0,0.5)
yy = sin(xx)
plt.plot(xx,yy,'k-',marker='o',markerfacecolor='none')
results in the following figure.
But I would like the lines connecting data points to start not from the center of each marker but from its borders.