I would love to have your input how to solve this issues.
I have a time series (x=date) ggplot with bars (y=cmass1), and my bars are on position="stack" using a factor (polymer) to display polymer types for each sample.
Each bar represents another sampling station (factor sample), and I would like to identify which bar is which station (factor "sample" in my data frame) and add the label above each bar.
I've come so far that I can show the "sample" labels, but then there appear multiple replicated labels (one for each data point in the stacked parts of the bar). But I need only one per bar!
Can someone help, how I can create one label per bar (above each bar) that identifies which sample it is (without manual annotation)?
Additional date display problem:
Also, on one date (11 November) I have two samples, and in this plot they are cumulated, but I would need them next to each - so two as stacked bars on one date (like with besides=TRUE, but that doesn't seem to work with stacked bars). Any help here?
I hope it is clear, and thanks so much for any help!
Cleo
The plot, where S1, S2 etc should be above each bar as a label
Dataframe view_partial
ggplot(Merg1[!(is.na(Merg1$campaign)),] ,
aes(date,y=cmass1,group_by(sample1), fill=polymer))+
geom_col(show.legend = T, alpha = 0.8, position="stack",
stat="identity")+
xlab("July 2021 November 2021 February 2022 July 2022") +
facet_grid(.~campaign, scales = "free_x",space = "free_x" )+
geom_point(aes(y=montsouris_mm*20 ),color="#A3009F",size=2.5, position="dodge")+
geom_point(aes(y=melun_mm*20 ),color="#558C8C",size=2.5, position="dodge")+
geom_point(aes(y=fauville_mm*20 ),color="#E8DB7D",size=2.5, position="dodge")+
scale_y_continuous(expand = c(0,0),limits=c(0, 1000), breaks = seq(0, 1000, by = 100),
sec.axis = sec_axis(~./20, name = "Precipitation (mm)",
breaks = seq(0, 50, by = 10))) +
scale_x_date(date_breaks = "1 day", labels = date_format("%d"))+
ylab(expression(bold(paste(~C[mass]~ (µg ~L^{-1}))))) +
theme(axis.text.x=element_text(color="black", size=12, angle=0, vjust=0.5),
axis.text.y=element_text(color="black", size=12, angle=0, vjust=0.5),
axis.ticks.x=element_blank(),
axis.title.x = element_text(size = 12,
color = "black",
face = "bold"),
strip.background = element_rect(color="white", fill="white", size=0.5,
linetype="solid"),
legend.text = element_text(color = "black",size = 12),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
panel.background = element_rect(size = 0.5,colour="#D4CDCB",
fill="white" ,linetype = 'solid'),
legend.key.height= unit(0.2, 'cm'),
legend.key.width= unit(0.4, 'cm'))+
scale_fill_manual(name = "", values = MPcol, breaks = c("abs","acrylic", "acrylic paints", "alkyd","epoxy", "pa", "pan_acrylic fibre", "pe", "polyester", "pp", "ps", "pu", "pvac", "pvc", "sbr", "vinyl copolymer"),
labels=c("Acrylonitrile butadiene styrene (ABS)","Acrylic", "Acrylic paint", "Alkyd", "Epoxy", "Polyamide (PA)", "Pan acrylic fibre", "Polyethylene (PE)", "Polyester (PET)", "Polypropylene (PP)", "Polystyrene (PS)", "Polyurethane (PU)", "Polyvinyl acetate (PVAC)", "Poly vinyl chloride (PVC)", "Styrene butadiene rubber (SBR)", "Vinyl copolymere"))+
theme(legend.position = "bottom",
legend.background = element_rect(fill = "#FFFCFB", # Background
colour = 1),
legend.title = element_text(family = "sans",
color = "black",
size = 10,
face = 2)) +
theme(panel.grid.minor = element_line(color = "#D4CDCB",
size = 0.15,
linetype = 2))+
theme(strip.text.x = element_text(size=14, face="bold",
vjust = 2, color="black")) +
#geom_text( label = label1, vjust = -1, position = position_dodge(0.90), size = 3, hjust=-0.5)+
labs(title = "Microplastics",
subtitle = "Mass Concentrations by Polymer Types",
caption = "Still missing S4 repeated samples and M1 in Campaign D. S4 in Campaign C cumulated repetaed samples. MPs >300µm are excluded, also natural particles are excluded.",
tag = "Fig. 5-1") +
theme(plot.title = element_text(family = "serif", # Font family
face = "bold", # Font face
color = 1, # Font color
size = 16, # Font size
hjust = 1, # Horizontal adjustment
vjust = 1, # Vertical adjustment
angle = 0, # Font angle
lineheight = 1, # Line spacing
margin = margin(5, 0, 0, 0)), # Margins (t, r, b, l)
plot.subtitle = element_text(family = "serif",
hjust = 1, size=14), # Subtitle customization
plot.caption = element_text(hjust = 0.25, size =11,
family = "serif",face = "italic"), # Caption customization
plot.tag = element_text(face = "italic"), # Tag customization
plot.title.position = "plot", # Title and subtitle position ("plot" or "panel")
plot.caption.position = "panel", # Caption position ("plot" or "panel")
plot.tag.position = "top") # Tag position
How do I implement dynamic data to my CorePlot? I'd like my graph to look like this:
How should I implement my JSON API and to decode the values to set it as X-axis?
JSON API: https://dcmicrogridiep.000webhostapp.com/datamainjson.php
This is my sample code for the CorePlot graph which uses hard coded values.
import Foundation
import SwiftUI
import CorePlot
class CalculatePlotData: ObservableObject {
var plotDataModel: PlotDataClass? = nil
func plotYEqualsX()
{
//set the Plot Parameters
plotDataModel!.changingPlotParameters.yMax = 10.0
plotDataModel!.changingPlotParameters.yMin = -5.0
plotDataModel!.changingPlotParameters.xMax = 10.0
plotDataModel!.changingPlotParameters.xMin = -5.0
plotDataModel!.changingPlotParameters.xLabel = "x"
plotDataModel!.changingPlotParameters.yLabel = "y"
plotDataModel!.changingPlotParameters.lineColor = .red()
plotDataModel!.changingPlotParameters.title = " y = x"
plotDataModel!.zeroData()
var plotData :[plotDataType] = []
for i in 0 ..< 120 {
//create x values here
let x = -2.0 + Double(i) * 0.2
//create y values here
let y = x * 8
let dataPoint: plotDataType = [.X: x, .Y: y]
plotData.append(contentsOf: [dataPoint])
}
plotDataModel!.appendData(dataPoint: plotData)
}
func ploteToTheMinusX()
{
//set the Plot Parameters
plotDataModel!.changingPlotParameters.yMax = 10
plotDataModel!.changingPlotParameters.yMin = -3.0
plotDataModel!.changingPlotParameters.xMax = 10.0
plotDataModel!.changingPlotParameters.xMin = -3.0
plotDataModel!.changingPlotParameters.xLabel = "x"
plotDataModel!.changingPlotParameters.yLabel = "y = exp(-x)"
plotDataModel!.changingPlotParameters.lineColor = .blue()
plotDataModel!.changingPlotParameters.title = "exp(-x)"
plotDataModel!.zeroData()
var plotData :[plotDataType] = []
for i in 0 ..< 60 {
//create x values here
let x = -8.0 + Double(i) * 5
//create y values here
let y = exp(-x)
let dataPoint: plotDataType = [.X: x, .Y: y]
plotData.append(contentsOf: [dataPoint])
}
plotDataModel!.appendData(dataPoint: plotData)
return
}
}
If you don't need the actual date values elsewhere in the app, you can just send the numbers in the "times" field provided by the API to the plot directly. You'll set the plot ranges based on those values and define a label formatter with the correct reference date to properly display the date values. Look at the DatePlot example app for a simple Swift example.
I'm plotting sunrise/sunset against time, so time goes along the X axis with iOS Charts (Daniel Gindi).
If I display the x labels as numbers they manifest correctly: If I swap them over to text (Jan - Dec) only Jan shows up???
Associated iOS Chart code:
// Setup X Axis
lineChartView.xAxis.axisMinimum = 0
lineChartView.xAxis.axisMaximum = 366
lineChartView.xAxis.granularityEnabled = true
lineChartView.xAxis.granularity = 30
lineChartView.xAxis.labelCount = 12
lineChartView.xAxis.axisLineWidth = 2
lineChartView.xAxis.axisLineColor = .black
lineChartView.xAxis.centerAxisLabelsEnabled = true
If I swap it over to literals then I only get Jan. All the values are populated. Any ideas?
Code: (n.b. putting labelCount before IndexAxisValueFormatter(values:months) makes no difference.)
// Setup X Axis
let months = ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sept","Oct","Nov","Dec"]
lineChartView.xAxis.axisMinimum = 0
lineChartView.xAxis.axisMaximum = 366
lineChartView.xAxis.granularityEnabled = true
lineChartView.xAxis.granularity = 30
lineChartView.xAxis.labelCount = 12
lineChartView.xAxis.valueFormatter = IndexAxisValueFormatter(values:months)
lineChartView.xAxis.axisLineWidth = 2
lineChartView.xAxis.axisLineColor = .black
lineChartView.xAxis.centerAxisLabelsEnabled = true
I have Label in my UIView which continuously changes values in between 80(min) to 475(Max) now I have run the progress bar status with respect to max and min value of label continuously. below where the code i have tried till now
if ampsMaxValue <= 80
{
ampsMaxValue = 80
ampsLabel.text = String(ampsMaxValue)
ampsprogressBar.progress = Float(0)
return
}
ampsMaxValue = ampsMaxValue - 1
ampsLabel.textColor = UIColor.white
ampsprogressBar.tintColor = UIColor.red
ampsLabel.text = String(ampsMaxValue)
v -= 0.1
ampsprogressBar.progress = Float(v)
}else{
if ampsMaxValue >= 475
{
ampsMaxValue = 475
ampsLabel.text = String(ampsMaxValue)
ampsprogressBar.progress = Float(1)
return;
}
ampsMaxValue = ampsMaxValue + 1
ampsLabel.textColor = UIColor.white
ampsprogressBar.tintColor = UIColor.red
ampsLabel.text = String(ampsMaxValue)
v += 0.1
ampsprogressBar.progress = Float(v)
}
I was able show the increased and decreased value by 0.1, but not solved it. need info about how calculate the exact increased and decreased value for the progress bar with respect to the label max an min value.
Try:
v = (ampsMaxValue - 80) / (475 - 80)
in code below it displays "SCORE: 100" or whatever however as the score / points change
the totals are over lapping one on top of the other and you cant read them ...
i want the old score erased / removed before displaying new score/points
ANY THOUGHTS HOW TO FIX this...this is LUA and using CORONA SDK
during my test i have sent print statements to try to troubleshoot sections
--Points is being calculated in another location
--UPDATE SCORE POINTS
local function updateScore(Points)
if WTF == 1 then
print ("SCORE: -->",Points)
--PointsText:removeSelf(PointsText)
PointsText = display.newText(Points,0,0,native.sytemFont,42)
PointsText.text = Points
PointsText.xscale = 0.5; PointsText.yscale = 0.5
PointsText:setTextColor(155,155,225)
PointsText.x = centerX * 1
PointsText.y = centerY - 150
ScoreTxt = display.newText("Score: ",0,0,native.systemFont,40)
ScoreTxt:setTextColor(220,50,50)
ScoreTxt.x = display.contentCenterX
ScoreTxt.y = display.contentCenterY-100
end
end
Every time you call updateScore you're creating a new text object. This code ensures you only create the text once.
local function updateScore(Points)
if PointsText == nil then
PointsText = display.newText(Points,0,0,native.sytemFont,42)
end
PointsText.text = Points
PointsText.xscale = 0.5; PointsText.yscale = 0.5
PointsText:setTextColor(155,155,225)
PointsText.x = centerX * 1
PointsText.y = centerY - 150
ScoreTxt = display.newText("Score: ",0,0,native.systemFont,40)
ScoreTxt:setTextColor(220,50,50)
ScoreTxt.x = display.contentCenterX
ScoreTxt.y = display.contentCenterY-100
end
You could also do:
local function updateScore(Points)
if PointsText then
PointsText:removeSelf()
end
PointsText = display.newText(Points,0,0,native.systemFont,42)
PointsText.text = Points
PointsText.xscale = 0.5; PointsText.yscale = 0.5
PointsText:setTextColor(155,155,225)
PointsText.x = centerX * 1
PointsText.y = centerY - 150
ScoreTxt = display.newText("Score: ",0,0,native.systemFont,40)
ScoreTxt:setTextColor(220,50,50)
ScoreTxt.x = display.contentCenterX
ScoreTxt.y = display.contentCenterY-100
end