I'm trying to plot a normal distribution curve (as a SeriesChartType.Spline) with a selected items location on that curve. My x-axis is a little messy so I'm trying to tidy it up but I can't figure a way to show the axis label at specific locations.
I'd like to show the value at {x(0), x(mean), x(n)} and also the x-axis value of the selected item's data-point on the curve.
I've tried playing with the
.ChartAreas(0).AxisX.Interval
but I don't necessarily have a standard interval range.
Is there a way I can display the x-axis label only at specified data points?
[EDIT]:
As suggested I implemented several custom labels for this chart. They are not exactly what I'd call intuitive to use but they did the job in the end.
'//create x-axis labels
mu = Math.Round(mu, 2, MidpointRounding.AwayFromZero)
bci = Math.Round(CDbl(bci), 2, MidpointRounding.AwayFromZero)
Dim muLabel = String.Format("{0}({1})", "ยต", mu)
'//Fit axis
With .ChartAreas(0)
With .AxisX
.MajorGrid.LineWidth = 0
.MajorTickMark.Enabled = false
.Minimum = 0
With .CustomLabels
.Add(New CustomLabel(0, 0.4, 0, 0, LabelMarkStyle.LineSideMark)) '//origin label
.Add(New CustomLabel(mu-10, mu + 10, muLabel, 0, LabelMarkStyle.LineSideMark)) '//mean label)
.Add(New CustomLabel(bci-10, bci + 10, bci.ToString, 0, LabelMarkStyle.LineSideMark)) '//index label
End With
With .LabelStyle
.Format = "{0.00}"
.Font = New Font("Microsoft Sans Serif", 8)
End With
...
The ranges I picked for the labels are a bit arbitrary. My data distribution is not going to change much immediately so I picked a range that looked reasonable with the font so the labels sit in the centre. Looks much more readable now: http://i.imgur.com/7buwdyk.png
You have a choice of either
Replacing the normal labels by CustomLabels. They are a bit tricky since you can't set their position. Instead you need two positions (FromPosition and ToPosition) to declare the range where the CustomLabel shall be centered. Note that once you use CustomLabels no normal ones will show.
Or you can add TextAnnotations. You can set AnchorX to the value you want and the Y position to the minimum of your y-values. Getting these right is also a little tricky, involving the axes of the Annotation and also the IsSizeAlwaysRelative which should be false.
Or you could code the Pre- or PostPaint events and Graphics.DrawString or TextRenderer.DrawText the text you want using the ValueToPixelPosition axes functions to get the coordinates. This may actually be the easiest to do..
You should be able to do this with custom labels (example here), but might need to do some extra fiddling to hide the normal labels (example here).
Related
I am using nested_facet() to plot a large number of experiments, yielding a 9x6 array. Each panel in the array is a stacked bargraph with variables indicated by color, same set of variables common to each row.
My code...
ggplot(data, aes(x=enzyme_drug, y=counts, fill = species)) +
geom_bar(position = "fill", stat = "identity") +
theme(axis.text.x = element_text(angle = 90)) +
guides(fill=guide_legend(ncol=1)) +
facet_grid(pH ~ combo, scales = "free")
The only problem with putting them all together into a facet grid is that the number of variables indicated by color in the figure legend is too high, resulting in adjacent colors that are hard to differentiate.
An easy way out of this would be to create a separate legend for each row, with the small number of variables for each row being much easier to differentiate.
Any ideas on how to do this?
The other alternative I realise is to loop the creation of separate facet_grids into a list and then put them together with ggarrange() - this yields unwieldy x-axis labels repeated for each row, although I could remove the x-axes manually for each row in the arrangement there must be a simpler method?
Thanks in advance...
I am using a line to estimate the slope of my graphs. the data points are in the same size. But look at these two pictures. the first one seems to have a larger slope but its not true. the second one has larger slope. but since the y-axis has different rate, the first one looks to have a larger slope. is there any way to fix the rate of y-axis, then I can see with my eye which one has bigger slop?
code:
x = np.array(list(range(0,df.shape[0]))) # = array([0, 1, 2, ..., 3598, 3599, 3600])
df1[skill]=pd.to_numeric(df1[skill])
fit = np.polyfit(x, df1[skill], 1)
fit_fn = np.poly1d(fit)
df['fit_fn(x)']=fit_fn(x)
df[['Hodrick-Prescott filter',skill,'fit_fn(x)']].plot(title=skill + date)
Two ways:
One, use matplotlib.pyplot.axis to get the axis limits of the first figure and set the second figure to have the same axis limits (using the same function) (could also use get_ylim and set_ylim, which are specific to the y-axis but require directly referencing the Axes object)
Two, plot both in a subplots figure and set the argument sharey to True (my preferred, depending on the desired use)
I am attempting to write a function using createJS to draw an arbitrary function and I'm having some trouble. I come from a d3 background so I'm having trouble breaking out of the data-binding mentality.
Suppose I have 2 arrays xData = [-10, -9, ... 10] and yData = Gaussian(xData) which is psuedocode for mapping each element of xData to its value on the bell curve. How can I now draw yData as a function of xData?
Thanks
To graph an arbitrary function in CreateJS, you draw lines connecting all the data points you have. Because, well, that's what graphing is!
The easiest way to do this is a for loop going through each of your data points, and calling a lineTo() for each. Because the canvas drawing API starts a line where you last 'left off', you actually don't even need to specify the line start for each line, but you DO have to move the canvas 'pen' to the first point before you start drawing. Something like:
// first make our shape to draw into.
let graph = new createjs.Shape();
let g = graph.graphics
g.beginStroke("#000");
xStart = xData[0];
yStart = yourFunction(xData[0]);
g.moveTo(xStart, yStart);
for( let i = 1; i < xData.length; i++){
nextX = xData[i], but normalized to fit on your graph area;
nextY = yourFunction(xData[i]), but similarly normalized;
g.lineTo(nextX, nextY);
}
This should get a basic version of the function drawing! Note that the line will be pretty jagged if you don't have a lot of data points, and you'll have to treat (normalize) your data to make it fit onto your screen. For instance, if you start at -10 for X, that's off the screen to the left by 10 pixels - and if it only runs from -10 to +10, your entire graph will be squashed into only 20 pixels of width.
I have a codepen showing this approach to graphing here. It's mapped to hit every pixel on the viewport and calculate a Y value for it, though, rather than your case where you have input X values. And FYI, the code for graphing is all inside the 'run' function at the top - everything in the PerlinNoiseMachine class is all about data generation, so you can ignore it for the purposes of this question.
Hope that helps! If you have any specific follow-up questions or code samples, please amend your question.
Create a simple stacked bar chart:
require(ggplot2)
g <- ggplot(mpg, aes(class)) +
geom_bar(aes(fill = drv, size=ifelse(drv=="4",2,1)),color="black",width=.5)
I can change the size values in size=ifelse(drv=="4",2,1) to lots of different values and I still get the same two line weights. Is there a way around this? (2,1) produces the same chart as (1.1,1) and (10,1). Ideally the thicker weight should be just a bit thicker than the standard outline, rather than ~10x bigger.
As added background, you can set size outside of aes() and have outline width scale as you'd expect, but I can't can't assign the ifelse condition outside of aes() without getting an error.
The two size values you give as aesthetics are just just arbitrary levels that are not taken at face value by ggplot.
You can use
ggplot(mpg, aes(class)) +
geom_bar(
aes(fill = drv, size = drv == "4"),
color = "black", width = .5) +
scale_size_manual(values = c(1, 2))
Where the values parameter allows you to specify the precise sizes for each level you define in the asesthetics.
In an X-Y scatter plot, I manually add text labels to data points via Point.DataLabel. Unfortunately I find that when points are crowded then it can be difficult to tell which series a label belongs to. Therefore I want to color my text labels to match the markers.
I am happy with the default markers and their colors, but unfortunately they contain MarkerForegroundColor = -1 and MarkerForegroundColorIndex = 0, no matter which series I look at. Furthermore, Application.ActivePresentation.ColorSchemes is empty. I note that point.MarkerStyle = xlMarkerStyleAutomatic.
I found that the colors correspond to the accent colors in the active Theme (only available in PowerPoint 2007 onwards):
presentation.SlideMaster.Theme.ThemeColorScheme.Colors(MsoThemeColorSchemeIndex.msoThemeAccent1 + series_i % 6);