In the Shiny dashboard tutorial of the Wikimedia foundation a screenshot is shown with a kind of horizontal stacked bar (the one with red, green, and blue "Full-text...OpenSearch..Prefix):
I have been searching everywhere, but I cannot find out how to create a bar like this. Can anyone point me in the right direction?
This is not a great answer, but it works. Requires learning some ggplot2 if you want to tweak it, and I tried to get rid of the border around the edges but it isn't gone completely. Still, the basic idea is here.
library(ggplot2)
mydf <- data.frame(labels = c('This', 'that', 'the other'),
percents = c(0.31, 0.15, 0.54))
mydf$pos <- pmax(0, cumsum(mydf$percents) - (0.5 * mydf$percents))
p <- ggplot(mydf, aes(x = NA, y = percents)) +
geom_bar(stat = 'identity', aes(fill = percents)) +
geom_text(color = 'white', aes(label = labels, y = pos)) +
coord_flip() +
guides(fill = FALSE) +
scale_x_discrete(expand = c(0, 0)) +
scale_y_discrete(expand = c(0, 0)) +
theme_void()
png('this_plot.png', width = 800, height = 30)
p
dev.off()
Related
I have made a pbiviz custom visual using developer tools of Normal distribution curve over a Histogram plot with R - ggplot2 and plotly libraries in a pbiviz.package
The visual works fine. Now I want to add interactivity of the Histogram with other Power BI visuals.
i.e. If user clicks on a bar of the Histogram, it should filter out a Table on my PBI report with rows relevant to the histogram bar data.
Considering the limitations of using R script with Power BI, I do not know if it is possible with my current visual as I am new to scripting.
Is there a better way (Typescript, JS, Python, etc.) other than what I have done to make an Interactive Histogram & Distribution Curve in Power BI?
This is the R script along with sample data and Visual Image
Histogram represents the projects falling in different durations
There are two bell curves - One for closed projects and Other for Active Projects
source('./r_files/flatten_HTML.r')
############### Library Declarations ###############
libraryRequireInstall("ggplot2");
libraryRequireInstall("plotly");
libraryRequireInstall("tidyverse");
libraryRequireInstall("scales");
libraryRequireInstall("htmlwidgets");
library(ggplot2)
library(tidyverse)
library(scales)
library(plotly)
theme_set(theme_bw())
##### Making DataSet for All Selected Projects #####
Duration <- dataset$Duration
Status <- (rep(dataset$ProjectStatus))
da <- data.frame(Duration,Status)
lenx <- length(Duration)
meanall <- mean(da$Duration)
sdx <- sd(da$Duration)
binwidth <- 30
font_label <- list(family = "Segoe UI", size = 21, colour = "black")
hovlabel <- list(bordercolor = "black", font = font_label)
#Filtering Out Closed Projects from Dataset
#Creating Data Frame for Closed Projects
closedproj <- dataset %>%
select(Duration,ProjectStatus) %>%
filter(ProjectStatus == "Closed")
closed <- closedproj$Duration
df <- data.frame(closed)
xclosed <- closedproj$
df2 <- data.frame(xclosed)
lenc <- length(xclosed)
mean_closed <- mean(df2$xclosed)
sdc <- sd(df2$xclosed)
a <-
(ggplot(da,aes(x=Duration, fill = Status, text = paste("Duration: ",x,"-", x + binwidth,"<br />Project Count", ..count..)))+
#Histogram
geom_histogram(aes(y=..count..),alpha=0.5, position='identity',binwidth = binwidth)+
# #Distribution Curve
annotate(
geom = "line",
x = da$Duration,
y = dnorm(da$Duration, mean = meanall, sd = sdx) * lenx * binwidth,
width = 3,
color = "red"
) +
annotate(
geom = "line",
x = df2$xclosed,
y = dnorm(df2$xclosed, mean = mean_closed, sd = sdc)* lenc * binwidth,
width = 3,
color = "blue"
) +
labs(
x = "Project Duration (Days)",
y = "Project_Count",
fill = "Project Status")+
#Mean
geom_vline(aes(xintercept=meanall),color="red",linetype="dashed",size = 0.8,label=paste("Mean :",round(meanall,0)))+
geom_vline(aes(xintercept=mean_closed),color="blue",linetype="dashed",size = 0.8,label=paste("Mean (Closed):",round(mean_closed,0)))+
# 1 Sigma
geom_vline(aes(xintercept = (meanall + sdx)), color = "red", size = 1, linetype = "dashed") +
geom_vline(aes(xintercept = (meanall - sdx)), color = "red", size = 1, linetype = "dashed")+
geom_vline(aes(xintercept = (mean_closed + sdc)), color = "blue", size = 1, linetype = "dashed") +
geom_vline(aes(xintercept = (mean_closed - sdc)), color = "blue", size = 1, linetype = "dashed")+
# Theme
theme(
plot.background = element_rect(fill = "transparent"),
legend.background = element_rect(fill = "lightgray"),
axis.title.x = element_text(colour = "Black",size = 18,face = "bold"),
axis.title.y = element_text(colour = "Black",size = 18,face = "bold"),
axis.text.x = element_text(colour = "Black",size = 15),
axis.text.y = element_text(colour = "Black",size = 15),
panel.grid.major = element_blank(), panel.grid.minor = element_blank())+
scale_x_continuous(labels = comma,
breaks = seq(0, max(Duration),50)) +
scale_y_continuous(labels = comma,
breaks = seq(0,max(Duration),10)))
############# Create and save widget ###############
p = ggplotly(a, tooltip = c("text")) %>%
style(hoverlabel = hovlabel) %>%
layout(legend = list(
orientation = "h",
x = 0,
y = 1.13,
title = list(text = "Project Status",font = list(family = "Segoe UI", size = 23)),
font = font_label
),
yaxis = list(title = list(standoff = 25L)),
xaxis = list(title = list(standoff = 25L)),
annotations = list(showarrow=FALSE,align = "left",valign = "top",x = 0.95, xref = "paper",yref = "paper",y = 0.955,
font = list(family = "Segoe UI", size = 22, color = "#cc0000"),
text = paste("Max Duration: ", comma(round(max(da$Duration),0)),
"<br>Mean (Closed): ", comma(round(mean_closed,0)),
"<br>Mean (All) : ", comma(round(meanall,0))))
) %>%
config(modeBarButtonsToRemove = c("select2d","hoverClosestCartesian", "lasso2d","hoverCompareCartesian","toggleSpikelines"), displaylogo = FALSE);
internalSaveWidget(p, 'out.html');
}
####################################################
################ Reduce paddings ###################
ReadFullFileReplaceString('out.html', 'out.html', ',"padding":[0-5]*,', ',"padding":0,')
What I expect is -- If user clicks on a bar of the Histogram, it should reflect on a Table visual on my PBI report with rows relevant to the histogram bar data.
Any help will be highly appreciated !
Regards
#The code below works fine in my scripts but not in R markdown.
library(tidyverse)
library(scales)
age <- kaggle_2020_Survey %>%
transmute(Q1 = as.factor(Q1)) %>%
filter(!is.na(Q1)) %>%
count(Q1) %>%
mutate(perc = n/sum(n)*100)
ggplot(age, aes(x = Q1, y = n)) + geom_col(fill = "darkblue", alpha =.7) +
geom_text (aes(x = Q1, y = n, label = paste0(round(perc,1), "%"),hjust = -.3), size = 3)
+
coord_flip() + labs(title = "Age of participants", x = "Percent", y = "Number",
subtitle = "Highest age group: 22-24") +
theme_classic()
#This is the error I am getting:
enter image description here
It could be that the object is in your environment but you forgot to include something like
library(tidyverse)
kaggle_2020_Survey <- read_csv("kaggle_2020_Survey.csv")
where you load in the data. When you knit a rmarkdown file it starts a new session each time so if the data isn't called in before you start doing stuff then it will throw that error
This answer goes into other solutions.
I am relatively new to R and am attempting to use gganimate to plot the occurrences of a given phenomenon on a map of the United States. I have a column frameid which is calculated by multiplying a column week by 100 and adding the nth occurrence of said phenomenon. So the 7th occurrence of a phenomenon in New York in the first week of the dataset would have a frameid of 107, and the 7th occurrence of a phenomenon in Los Angeles would also have a frameid of 107. I am passing frameid into transition_states, but the problem is that I only want to display the week (i.e. everything but the last two characters, as the occurrences could never conceivably exceed 99), so I need to manipulate frameid somehow. The attempted solution:
labs(title = "My Title",
subtitle = paste("2019, Week",
substring("{closest_state}", 1, nchar("{closest_state}")-2)))
Returns 50 warnings, the first of which is "1: Cannot get dimensions of plot table. Plot region might not be fixed" and the last 49 of which are "Expecting '}'".
I have also tried:
gsub('.{3}$', '', "{closest_state}")
Which returns a similar error. Is there a solution or a workaround to this problem or can "{closest_state}" not be manipulated?
Here is the reproducible code:
library(ggplot2)
library(gganimate)
library(fiftystater)
sample <- data.frame(
frameid = c(101, 101, 101, 102, 102, 102, 201, 201, 201),
latitude = c(38.02262, 38.99691, 41.31194, 27.00071,
28.539, 30.2836, 38.02262, 38.03112,
40.21603),
longitude = c(-84.50521, -104.84369, -105.56906, -108.4121,
-81.4028, -97.73234, -84.50521, -78.51371,
-85.4177)
)
fortynine_states <- fifty_states %>%
filter(id != "alaska")
my_plot <- sample %>%
ggplot(aes(x = longitude, y = latitude)) +
geom_polygon(data = fortynine_states,
mapping = aes(long, lat, group = group),
fill = "white", color = "black") +
geom_point(aes(alpha = 0.2, color = "red")) +
coord_map() +
labs(title = "My Title",
subtitle = paste("2019, Week",
substring("{closest_state}", 1, nchar("{closest_state}")-2))) +
transition_states(frameid, transition_length = 2) +
exit_fade()
animate(my_plot, duration = 5, fps = 20, width = 400, height = 300, renderer = gifski_renderer())
I'm using the Python(xy) package and QT designer. Python(xy) has a built-in MPL widget for QT which is what I'm using. Works fine for me until I replot: Is there any way to make the current setup (pyplot) redraw?
Here's my code:
def mpl_plot(self, plot_page, replot = 0): #Data stored in lists
if plot_page == 1: #Plot 1st Page
plt = self.mplwidget.axes
fig = self.mplwidget.figure #Add a figure
fig = self.mplwidget.figure
if plot_page == 2: #Plot 2nd Page
plt = self.mplwidget_2.axes
fig = self.mplwidget_2.figure #Add a figure
if plot_page == 3: #Plot 3rd Page
plt = self.mplwidget_3.axes
fig = self.mplwidget_3.figure #Add a figure
par1 = fig.add_subplot(1,1,1)
par2 = fig.add_subplot(1,1,1)
#Add Axes
ax1 = par1.twinx()
ax2 = par2.twinx()
ax2.spines["right"].set_position(("outward", 25))
self.make_patch_spines_invisible(ax2)
ax2.spines["right"].set_visible(True)
impeller = str(self.comboBox_impellers.currentText()) #Get Impeller
fac_curves = self.mpl_factory_specs(impeller)
fac_lift = fac_curves[0]
fac_power = fac_curves[1]
fac_flow = fac_curves[2]
fac_eff = fac_curves[3]
fac_max_eff = fac_curves[4]
fac_max_eff_bpd = fac_curves[5]
fac_ranges = self.mpl_factory_ranges()
min_range = fac_ranges[0]
max_range = fac_ranges[1]
#Plot Chart
plt.hold(True) #Has to be included for multiple curves
plt.plot(fac_flow, fac_lift, 'b', linestyle = "dashed", linewidth = 1)
#plt.plot(flow,f_lift,'b.') #Plot datapoints only
#Plot Factory Power
ax1.plot(fac_flow, fac_power, 'r', linestyle = "dashed", linewidth = 1)
#ax1.plot(flow,f_power,'r.') #Plot datapoints only
ax2.plot(fac_flow, fac_eff, 'g', linestyle = "dashed", linewidth = 1)
#Plot x axis minor tick marks
minorLocatorx = AutoMinorLocator()
ax1.xaxis.set_minor_locator(minorLocatorx)
ax1.tick_params(which='both', width= 0.5)
ax1.tick_params(which='major', length=7)
ax1.tick_params(which='minor', length=4, color='k')
#Plot y axis minor tick marks
minorLocatory = AutoMinorLocator()
plt.yaxis.set_minor_locator(minorLocatory)
plt.tick_params(which='both', width= 0.5)
plt.tick_params(which='major', length=7)
plt.tick_params(which='minor', length=4, color='k')
#Make Border of Chart White
#Plot Grid
plt.grid(b=True, which='both', color='k', linestyle='-')
#set shaded Area
plt.axvspan(min_range, max_range, facecolor='#9BE2FA', alpha=0.5) #Yellow rectangular shaded area
#Set Vertical Lines
plt.axvline(fac_max_eff_bpd, color = '#69767A')
bep = fac_max_eff * 0.90
bep_corrected = bep * 0.90
ax2.annotate('BEP', xy=(fac_max_eff_bpd, bep_corrected), xycoords='data',
xytext=(-50, 30), textcoords='offset points',
bbox=dict(boxstyle="round", fc="0.8"),
arrowprops=dict(arrowstyle="-|>",
shrinkA=0, shrinkB=10,
connectionstyle="angle,angleA=0,angleB=90,rad=10"),
)
#Set Scales
plt.set_ylim(0,max(fac_lift) + (max(fac_lift) * 0.40)) #Pressure
#plt.set_xlim(0,max(fac_flow))
ax1.set_ylim(0,max(fac_power) + (max(fac_power) * 0.40)) #Power
ax2.set_ylim(0,max(fac_eff) + (max(fac_eff) * 0.40)) #Effiency
# Set Axes Colors
plt.tick_params(axis='y', colors='b')
ax1.tick_params(axis='y', colors='r')
ax2.tick_params(axis='y', colors='g')
# Set Chart Labels
plt.set_xlabel("BPD")
plt.set_ylabel("Feet" , color = 'b')
#ax1.set_ylabel("BHP", color = 'r')
#ax1.set_ylabel("Effiency", color = 'g')
I recommended
figure.canvas.draw()
figure.canvas.update()
This is from the documentation of matplotlib, and could you please delete any unnecessary code? That will help others to quickly find your problem.
Someone suggested earlier that I call fig.canvas.draw() to refresh my plot with new data. It worked great on the main plot, however I also have subplots included in the chart. The subplots are getting redrawn, however the old subplots, along with axes and other items are not getting cleared. Does anyone know how to get rid of the old subplot curves and other items when I replot?
def mpl_plot(self, plot_page, replot = 0): #Data stored in lists
if plot_page == 1: #Plot 1st Page
plt = self.mplwidget.axes
fig = self.mplwidget.figure #Add a figure
if plot_page == 2: #Plot 2nd Page
plt = self.mplwidget_2.axes
fig = self.mplwidget_2.figure #Add a figure
if plot_page == 3: #Plot 3rd Page
plt = self.mplwidget_3.axes
fig = self.mplwidget_3.figure #Add a figure
if replot == 1:
#self.mplwidget_2.figure.clear()
print replot
par1 = fig.add_subplot(111)
par2 = fig.add_subplot(111)
#Add Axes
ax1 = par1.twinx()
ax2 = par2.twinx()
impeller = str(self.comboBox_impellers.currentText()) #Get Impeller
fac_curves = self.mpl_factory_specs(impeller)
fac_lift = fac_curves[0]
fac_power = fac_curves[1]
fac_flow = fac_curves[2]
fac_eff = fac_curves[3]
fac_max_eff = fac_curves[4]
fac_max_eff_bpd = fac_curves[5]
fac_ranges = self.mpl_factory_ranges()
min_range = fac_ranges[0]
max_range = fac_ranges[1]
#bep = fac_ranges[2]
#Plot Chart
plt.hold(False) #Has to be included for multiple curves
#Plot Factory Pressure
plt.plot(fac_flow, fac_lift, 'b', linestyle = "dashed", linewidth = 1)
#Plot Factory Power
ax1.plot(fac_flow, fac_power, 'r', linestyle = "dashed", linewidth = 1)
ax2.plot(fac_flow, fac_eff, 'g', linestyle = "dashed", linewidth = 1)
#Move spines
ax2.spines["right"].set_position(("outward", 25))
self.make_patch_spines_invisible(ax2)
ax2.spines["right"].set_visible(True)
#Plot x axis minor tick marks
minorLocatorx = AutoMinorLocator()
ax1.xaxis.set_minor_locator(minorLocatorx)
ax1.tick_params(which='both', width= 0.5)
ax1.tick_params(which='major', length=7)
ax1.tick_params(which='minor', length=4, color='k')
#Plot y axis minor tick marks
minorLocatory = AutoMinorLocator()
plt.yaxis.set_minor_locator(minorLocatory)
plt.tick_params(which='both', width= 0.5)
plt.tick_params(which='major', length=7)
plt.tick_params(which='minor', length=4, color='k')
#Make Border of Chart White
#Plot Grid
plt.grid(b=True, which='both', color='k', linestyle='-')
#set shaded Area
plt.axvspan(min_range, max_range, facecolor='#9BE2FA', alpha=0.5) #Yellow rectangular shaded area
#Set Vertical Lines
plt.axvline(fac_max_eff_bpd, color = '#69767A')
#BEP MARKER *** Can change marker style if needed
bep = fac_max_eff * 0.90 #bep is 90% of maximum efficiency point
bep_corrected = bep * 0.90 # We knock off another 10% to place the arrow correctly on chart
ax2.annotate('BEP', xy=(fac_max_eff_bpd, bep_corrected), xycoords='data', #Subtract 2.5 shows up correctly on chart
xytext=(-50, 30), textcoords='offset points',
bbox=dict(boxstyle="round", fc="0.8"),
arrowprops=dict(arrowstyle="-|>",
shrinkA=0, shrinkB=10,
connectionstyle="angle,angleA=0,angleB=90,rad=10"),
)
#Set Scales
plt.set_ylim(0,max(fac_lift) + (max(fac_lift) * 0.40)) #Pressure
#plt.set_xlim(0,max(fac_flow))
ax1.set_ylim(0,max(fac_power) + (max(fac_power) * 0.40)) #Power
ax2.set_ylim(0,max(fac_eff) + (max(fac_eff) * 0.40)) #Effiency
# Set Axes Colors
plt.tick_params(axis='y', colors='b')
ax1.tick_params(axis='y', colors='r')
ax2.tick_params(axis='y', colors='g')
# Set Chart Labels
plt.set_xlabel("BPD")
plt.set_ylabel("Feet" , color = 'b')
#To redraw plot
fig.canvas.draw()