altair - aligning tick marks with center of bars in bar plot - bar-chart

How do I center tick marks in the middle of the bars of a bar chart?
title = 'Submissions from Aug 2018 to Feb 2020 by Month'
chart = alt.Chart(df_US).mark_bar(size = 25,
color = 'black').encode(
x=alt.X('yearmonth(Time_Received):T',
axis =alt.Axis(format = "%b%y",
tickCount = 20,
tickBand = 'center')),
y='count(Time_Received)'
).configure_axisX( tickBand = 'center'
).properties(
width = 900,
title = title
).configure_axis(
grid=False
)

Change 'yearmonth(Time_Received):T' to 'yearmonth(Time_Received):O': this will make it an ordinal (i.e. ordered categorical) encoding, and the labels will appear by default at the center of each category.

Related

Is it possible to arrange graphs and filters in an R plot output?

I have created a small dashboard using bscols( from the crosstalkpackage. It consists of plotly graphs and their respective filter_checkboxes.
It looks pretty messy now, as the filters are not vertically aligned with their corresponding plots.
HTML_graphic
As indicated, I would like the first two checkbox sets to appear next to the second line graph (nothing to appear next to the first line graph); and the second two checkbox sets to appear next to the third line graph.
Also, I would like to create some vertical space between the three elements, as indicated by the brown and black horizontal lines.
The best solution would be to set the height of the html elements inside the bscols() command. Because in the future, I would like to programmatically save multiple of these outputs using htmltools::save_html.
The next best would be to have the output of that command somehow converted to html and add html code like line breaks or heights.
Neither I know how to do.
I came across this related question but it is unanswered: Arrange crosstalk graphs via bscols
Any suggestions on how to solve my problem?
My code
{r 002_Auto App Doc Vol_Invoice group delta plot - plot code, echo = FALSE}
# Setup of the legend for invoice plot
invoice_plot_legend <- list(
font = list(
family = "sans-serif",
size = 12,
color = "#000"),
title = list(text="<b> Delta previous month by division </b>"),
bgcolor = "#E2E2E2",
bordercolor = "#FFFFFF",
borderwidth = 2,
layout.legend = "constant",
traceorder = "grouped")
# The Shared Data format is needed for crosstalk to be able to filter the dataset upon clicking the checkboxes (division filters):
shared_invoice <- SharedData$new(Auto_App_Doc_Vol_invoiceg_plotting_tibble)
shared_invoice_KPI <- SharedData$new(Auto_App_Doc_Vol_KPI)
shared_abs <- SharedData$new(Auto_App_Doc_Vol_plotting_tibble_diff_abs)
# Setup of a bscols html widget; widths determines the widths of the input lists (here, 2: the filters, 10: the plot and legend)
# Overall KPI and invoice group plot
library(htmlwidgets)
crosstalk::bscols(
widths = c(2, 10),
list(
crosstalk::filter_checkbox("Division",
label = "Division",
sharedData = shared_invoice,
group = ~Division),
crosstalk::filter_checkbox("Rechnungsgruppe",
label = "Invoice group",
sharedData = shared_invoice,
group = ~Rechnungsgruppe),
crosstalk::filter_checkbox("Rechnungsgruppe",
label = "Invoice group",
sharedData = shared_abs,
group = ~Rechnungsgruppe),
crosstalk::filter_checkbox("Division",
label = "Division",
sharedData = shared_abs,
group = ~Division)
)
,
list(
plot_ly(data = shared_invoice_KPI, x = ~Freigabedatum_REAL_YM, y = ~KPI_current_month, meta = ~Division,
type = "scatter",
mode = "lines+text",
text = ~KPI_current_month,
textposition='top center',
hovertemplate = "%{meta}",
color = ~Diff_KPI_pp)
%>%
layout(legend = invoice_plot_legend,
title = "Automatically Approved Document Volume",
xaxis = list(title = 'Release date'),
yaxis = list(title = '%'))
,
plot_ly(data = shared_invoice, x = ~Freigabedatum_REAL_YM, y = ~n,
type = "scatter",
mode = "lines",
text = ~Rechnungsgruppe_effort,
hoverinfo = "y+text",
color = ~Difference_inline
)
%>%
layout(legend = invoice_plot_legend,
title = " ",
xaxis = list(title = 'Release date'),
yaxis = list(title = '# of Approved Documents'))
,
plot_ly(data = shared_abs, x = ~Freigabedatum_REAL_YM, y = ~n,
type = "scatter",
mode = "lines",
text = ~Lieferantenname,
hoverinfo = "y+text",
color = ~Lieferantenname_text
)
%>%
layout(legend = vendor_plot_legend,
title = "by vendor absolute delta previous month all documents",
xaxis = list(title = 'Release date'),
yaxis = list(title = '# of Approved Documents w/ & w/o effort')
)
)
)
Thank you so much!

How to effectively adjust graph margin or padding in dash plotly

I have plotted two graphs using plotly dash. But when the y-axis / x-axis tick size is more it gets cut off.
Y-axis :
Code :
data = [go.Scatter(x = df[df['S2PName-Category']==category]['S2BillDate'],
y = df[df['S2PName-Category']==category]['totSale'],
mode = 'markers+lines',
name = category) for category in df['S2PName-Category'].unique()]
layout = go.Layout(title='Category Trend',
xaxis = dict(title = 'Time Frame', tickformat = '%d-%b-%y'),
yaxis = dict(tickprefix= '₹', tickformat=',.2f',type='log'),
hovermode = 'closest',
plot_bgcolor = colors['background'],
paper_bgcolor = colors['background'],
font = dict(color = colors['text'])
)
X-Axis :
Code :
data = [go.Scatter(x = df[df['S2PName']==item]['S2BillDate'],
y = df[df['S2PName']==item]['totSale'],
mode = 'markers+lines',
name = item) for item in items]
layout = go.Layout(title='Category Trend',
xaxis = dict(title = 'Time Frame' , tickformat = '%d-%b'),
yaxis = dict(tickprefix= '₹', tickformat=',.2f',type='log',autorange = True),
hovermode = 'closest',
plot_bgcolor = colors['background'],
paper_bgcolor = colors['background'],
font = dict(color = colors['text'])
)
In the above 2 graphs , as the length of the tick value increases, it gets cut off . Is there a better way to handle this ?
Credit for #Flavia Giammarino in comments for the reference to the docs. I'm posting the answer for completeness.
https://plotly.com/python/setting-graph-size/
From that link the example below shows how to set margin:
fig.update_layout(
margin=dict(l=20, r=20, t=20, b=20),
)
Where l r t b correspond to left, right, top, bottom.
I had a similar problem with some Dash/Plotly charts and long y axis labels being truncated or hidden. There didn't seem to be much information or documentation on this issue, so it took a while to solve.
Solution: add this code to the layout settings to prevent truncation of the y axes labels:
fig.update_layout(
yaxis=dict(
automargin=True
)
)
or you can update the yaxes setting specifically:
fig.update_yaxes(automargin=True)
Update: I tried another version of Plotly (5.10 or above) which mentions setting the automargin setting to any combination of automargin=['left+top+right+bottom'] with similar results. This still seems a bit unstable and doesn't solve all possible scenarios or corner cases, but works fine in most cases, especially when the browser window is maximized.

A way to scroll a layout's widgets using mouse?

Can you help me on how to scroll a layout's content using mouse? Or is it possible?
I created this notification-center widget and I used wibox.layout.fixed.vertical() to act the storage of the widgets/notifications. My problem is having too many widgets will consume all the space and there will be no enough space to display the other widgets. So I've been trying to make the widget inside the wibox.layout.fixed.vertical() scrollable but I'm always reaching a dead end. I also tried the wibox.container.scroll but as the documentation says:
Please note that mouse events do not propagate to widgets inside of the scroll container.
This is the simple code I'm using:
-- Layout
local notifbox_layout = wibox.layout.fixed.vertical()
-- Add these textbox widgets to layout
-- Make this widgets scrollable if there's too many of them
notifbox_layout:insert(1, wibox.widget.textbox('String 1'))
notifbox_layout:insert(1, wibox.widget.textbox('String 2'))
notifbox_layout:insert(1, wibox.widget.textbox('String 3'))
notifbox_layout:insert(1, wibox.widget.textbox('String 4'))
notifbox_layout:insert(1, wibox.widget.textbox('String 5'))
-- Mouse event
notifbox_layout:buttons(
gears.table.join(
awful.button(
{},
4,
nil,
function()
-- some magic here to scroll up
end
),
awful.button(
{},
5,
nil,
function()
-- some magic here to scroll down
end
)
)
)
This is the notification center with no enough space to show the other widgets
Sorry if I explained this bad. I'm not really that good in english.
Nevermind. I tried Uli Schlachter's answer here. And it works perfectly. I modified it a bit and then it looks like this.
local w = wibox{ x = 100, y = 100, width = 100, height = 20, visible = true }
my_wiget = function()
return some_widget
end
local own_widget = wibox.widget.base.make_widget()
local offset_x, offset_y = -20, 0
function own_widget:layout(context, width, height)
-- No idea how to pick good widths and heights for the inner widget.
return { wibox.widget.base.place_widget_at(my_widget(), offset_x, offset_y, 200, 40) }
end
own_widget:buttons(
awful.util.table.join(
awful.button(
{},
4,
function()
if offset_y <= 490 then
offset_y = offset_y + 5
end
own_widget:emit_signal("widget::layout_changed")
end
),
awful.button(
{},
5,
function()
if offset_y >= 5 then
offset_y = offset_y - 5
end
own_widget:emit_signal("widget::layout_changed")
end
)
)
)
w:set_widget(own_widget)

To display stacked value within the stacked bar using jqplot

I am using jqplot to display graph sales of month.i used horizontal bar graph for that,i want to display value of each stacked bar within the bar.
I am tried using following code,
this.cfg.seriesDefaults = {
renderer:$.jqplot.BarRenderer,
rendererOptions: {
shadowOffset: 0,
barWidth :'30',
barDirection: 'horizontal',
highlightMouseDown: true
},
pointLabels: {show: true ,
hideZeros: true,
formatString: '%d',
// xpadding : -90
xpadding: 20, ypadding: 50,
// edgeTolerance: -55
location :'w'
}
but it displayed pointlabels within the bar for 1 st stacked region correct value displayed but for last it displayed total of stacked bar.
i want to disaplay each region value within the bar not total.

barplot xlim shifts axis -> offset to axis at=midpoints missing

I have the following problem – it is purely an ascetic one but it bothers me that it is not looking nicely:
I generate a simple sideways barplot with ticks at the bottom of the bars. The default setting generates an x-axis which is shorter than my bars (figure 1). To solve this I included xlim. Once I do that the x-axis is slightly shifted to the left so the y-axis is touching the bars (figure 2). This does not look nice at all. I guess xlim somehow overwrite a default parameter but I could not find which. I would be grateful for any suggestions!
rm(list=ls())
data<-c(69,500,597)
names(data)<-c("text1", "text2", "text3")
midpoints<-barplot(data, beside=T, space=1, xlim=c(0,600))
filename=paste("orig.pdf", sep="")
pdf(file=filename, width=10, height =5)
par(mar=c(4,9,1,4))
barplot(data, beside=T, xlab=expression(paste("Text")),
axes=T, cex.lab=2, cex.axis=2, cex.names=2, font.axis = 2,
col=c("grey"), horiz=T, las=1, font.lab=2, space=1,
names.arg=colnames(data))
axis(side = 2, at = midpoints , labels = F, cex.axis=1.5)
dev.off()
filename=paste("with_limit.pdf", sep="")
pdf(file=filename, width=10, height =5)
lim<-c(0,600)
par(mar=c(4,9,1,4))
barplot(data, beside=T, xlab=expression(paste("Text")),
axes=T, cex.lab=2, cex.axis=2, cex.names=2, font.axis = 2,
col=c("grey"), horiz=T, las=1, font.lab=2, space=1,
names.arg=colnames(data), xlim=lim)
axis(side = 2, at = midpoints , labels = F, cex.axis=1.5)
dev.off()
Figure 1
Figure 2
Meanwhile I did find two possible answers both not perfect but working.
The first one is to work with xaxs="r" but for my taste now the offset is too large.
filename=paste("solution1.pdf", sep="")
pdf(file=filename, width=10, height =5)
lim<-c(0,600)
par(mar=c(4,9,1,4))
barplot(data, beside=T, xlab=expression(paste("Text")),
axes=T, cex.lab=2, cex.axis=2, cex.names=2, font.axis = 2,
col=c("grey"), horiz=T, las=1, font.lab=2, space=1,
names.arg=colnames(data), xlim=lim, xaxs="r")
axis(side = 2, at = midpoints , labels = F, cex.axis=1.5)
dev.off()
Solution1
The second option is to have xlim starting in the negative. This has the disadvantage of tuning the offset by hand. In my case I had multiple figures and I wanted it always to be the same so I used (here) 2% of the maximum 600 -> 12. For all others I also used 2% of the maximum. That worked nicely in the end.
filename=paste("solution2.pdf", sep="")
pdf(file=filename, width=10, height =5)
lim<-c(-12,600)
par(mar=c(4,9,1,4))
barplot(data, beside=T, xlab=expression(paste("Text")),
axes=T, cex.lab=2, cex.axis=2, cex.names=2, font.axis = 2,
col=c("grey"), horiz=T, las=1, font.lab=2, space=1,
names.arg=colnames(data), xlim=lim)
axis(side = 2, at = midpoints , labels = F, cex.axis=1.5)
dev.off()
Solution2